HDU-5238 계산기

제목 설명

대해 주어 \ (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;
}

추천

출처www.cnblogs.com/dsjkafdsaf/p/11572887.html