제목 설명
대해 주어 \ (X \) 다음과 같이 표현 보인다 \을 (4 + 2 × ^ × 6 8 3 + \이..)
는 다음과 같이 계산된다 .. \ ((((X × 4) +2) 3 ^ +8) × 6 \)
오퍼레이터 만 더하기, 곱하기, 지수 세 종류가 주어진 화학식 \ N- (\) 보조 동작.
용 \ (m의 \) 시간이 주어진 동작 :
1. 소정의 표현 \ (X \) 값 및 화학식의 원래 순서의 결과 \ (29,393 \) 계수;
도 2는 도시 \ (K \) 위치에 운전자와 사업자 뒤에 디지털 변화. 이러한 작업의 완료.
입력
데이터의 여러 세트.
\ (1≤n, m≤50000 \)
산출
각각의 데이터 출력의 답.
샘플 입력
2
5 4
*4
+2
^3
+8
*6
1 2
1 3
2 3 *5
1 3
4 3
*4
^4
+4
*10
1 1
2 3 ^4
1 1
샘플 출력
Case #1:
6048
16512
468
Case #2:
2600
4107
의이 이상한 계수를 살펴 보자 \ (29,393 = 7 * 13 * 17 * 19 \) .
무엇을 사용하기 위해 무엇입니까? 의 아래를 살펴 보자.
우선, 우리는 쿼리의 숫자를 통해 빠르게 갈 필요 (n \) \ 작업의 값을, 우리는 작업의 신속한 수정을 지원해야합니다.
데이터 구조는 우리가 직접 트리 라인의 생각 범위 쿼리뿐만 아니라, 수정할 수 있습니다.
우리가 어떻게 전송합니까?
현재 구간 들어 \ (L, R & 중위 \) , 번호 \ (NUM \) , 미지수는 \ (X \) 의 결과 \ (F. (X, L, R & LT, NUM) \) .
두 개의 하위 섹션을 병합 고려하십시오.
세트 \ (브로 = F (X 축, L, MID, NUM << 1 | 1) \) , 즉 \ (X \) 후에 왼쪽 서브 간격 응답.
그렇다면 우리는이 \ (F (X 축, L, R, NUM) = F (브로, MID + 1, R, NUM << 1 | 1) \) .
그래서 우리는 신속하게 해결 트리 라인을 사용할 수 있습니다.
우리는 면밀한 관찰, 계수 걸릴 \ (29,393 \)를 , 세그먼트의 수는 같거나 계수 이하 각 번호에 대한 대답을 저장합니다.
공간적 복잡도 인 \ (O (4 * N 개의 계수 *) \) , 시간 복잡도이다 \ (O (N * * log_n 계수) \) .
어느 시간이나 공간을 여유가 없다.
이제, 이전에 언급 살펴 보자 \ (29,393 \) .
우리는로를 분해 \ (7 * 13 * 17 * 19 \) .
우리는이를 위해, 발견 \ (4 \) 시간과 공간의 복잡성 계수와 같은 숫자 저렴합니다.
그리고 현재하자 \ (X \) 이 후 \을 (4 \) 응답 모듈 번호입니다 (res_i의 \) \ 최종 대답은 (ANS \) \를 , 우리가 가진 :
\ [\를 {케이스} 시작 Ans By의 = RES_1 \ % P_1 \\ Ans By의 = res_2 \ %
P_2 \\ Ans By의 = res_3 \ % p_3 \\ Ans By의 = res_4 \ % p_4 끝 \ {사례} \] 우리가 직접 해결하기 위해 중국 잉여 정리를 사용합니다.
#include <cstdio>
#include <iostream>
using namespace std;
#define LL long long
#define reg register
#define clr(a,b) memset(a,b,sizeof a)
#define Mod(x) (x>=mod)&&(x-=mod)
#define abs(a) ((a)<0?-(a):(a))
#define debug(x) cerr<<#x<<"="<<x<<endl;
#define debug2(x,y) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
#define debug3(x,y,z) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
#pragma GCC optimize(2)
inline int Read(void) {
int res=0,f=1;
char c;
while(c=getchar(),c<48||c>57)if(c=='-')f=0;
do res=(res<<3)+(res<<1)+(c^48);
while(c=getchar(),c>=48&&c<=57);
return f?res:-res;
}
template<class T>inline bool Min(T &a, T const&b) {
return a>b?a=b,1:0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a<b?a=b,1:0;
}
const int N=5e4+5,M=1e5+5,Prime[]= {7,13,17,19};
bool MOP1;
int A[N];
char op[N];
struct SEG {
int val[5][25][N<<2];
inline void up(int num) {
ret(i,0,4)ret(j,0,Prime[i]) {
int nxt=val[i][j][num<<1];
val[i][j][num]=val[i][nxt][num<<1|1];
}
}
inline int calc(int a,char op,int b,int mod) {
if(op=='+')return (a+b)%mod;
if(op=='*')return (a*b)%mod;
int res=1;
while(b) {
if(b&1)res=res*a%mod;
a=a*a%mod,b>>=1;
}
return res;
}
inline void build(int L,int R,int num) {
if(L==R) {
rep(i,0,3)ret(j,0,Prime[i])val[i][j][num]=calc(j,op[L],A[L],Prime[i]);
return;
}
int mid=(L+R)>>1;
build(L,mid,num<<1);
build(mid+1,R,num<<1|1);
up(num);
}
inline void update(int L,int R,int num,int pos) {
if(L==R) {
rep(i,0,3)ret(j,0,Prime[i])val[i][j][num]=calc(j,op[L],A[L],Prime[i]);
return;
}
int mid=(L+R)>>1;
if(pos<=mid)update(L,mid,num<<1,pos);
else update(mid+1,R,num<<1|1,pos);
up(num);
}
} tr;
int n,res[N],mod[N],a[N],pos[N];
int Exgcd(int a, int b, int &x, int &y) {
if(!b) {
x=1,y=0;
return a;
}
int g=Exgcd(b,a%b,y,x);
y-=a/b*x;
return g;
}
inline int Excrt(void) {
mod[1]=7,mod[2]=13,mod[3]=17,mod[4]=19;
int M=mod[1],ans=res[1],x,y;
rep(i,2,4) {
int g=Exgcd(M,mod[i],x,y);
x*=(res[i]-ans)/g,y=mod[i]/g,x=(x%y+y)%y;
ans=M*x+ans,M=M/g*mod[i],ans%=M;
}
int z=(ans%M+M)%M;
return z;
}
bool MOP2;
inline void _main(void) {
int T=Read(),Case=0;
while(T--) {
printf("Case #%d:\n",++Case);
int n,m;
scanf("%d%d",&n,&m),getchar();
char c;
rep(i,1,n)scanf("%c%d",op+i,&A[i]),getchar();
tr.build(1,n,1);
while(m--) {
int Op,pos;
scanf("%d%d",&Op,&pos);
if(Op==1) {
rep(i,0,3)res[i+1]=tr.val[i][pos%Prime[i]][1];
printf("%d\n",Excrt());
} else {
getchar(),scanf("%c%d",op+pos,&A[pos]);
tr.update(1,n,1,pos);
}
}
}
}
signed main() {
_main();
return 0;
}