HDU-5238 Calculator

Title Description

Given about \ (X \) expression, looks as follows: \ (. 4 + 2 × ^ ×. 6. 8. 3 + \)
is calculated as follows: \ ((((X ×. 4) +2). 3 ^ +8) × 6 \)
operator only plus, multiplication, exponentiation three kinds, there are given formula \ (n-\) secondary operation.
For \ (m \) times a given operation:

1. The representation of a given \ (X \) values, and the result of the original order of Formula \ (29393 \) modulus;

2 shows a \ (K \) digital change behind operator and operators on location. Completion of these operations.

Input

Multiple sets of data.

\(1≤n,m≤50000\)

Output

For each data output answers.

Sample Input

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

Sample Output

Case #1:
6048
16512
468
Case #2:
2600
4107

Let's look at this strange modulus \ (29393 = 7 * 13 * 17 * 19 \) .

For what use is it? Let's look down.

First of all, we need to go quickly through a number of queries that \ (n \) value of operations, and we need to support rapid modification of the operation.

Data structure to be modified, as well as range query us directly think of the tree line.

How do we transfer it?


For the current interval \ (L, R & lt \) , numbered \ (NUM \) , the unknowns are \ (X \) is the result of \ (F. (X, L, R & lt, NUM) \) .

Consider merging the two sub-sections.

Set \ (Val = F (the X-, L, MID, NUM << 1 | 1) \) , namely \ (x \) after the left subinterval answer.

Then we have a \ (F (the X-, L, R, NUM) = F (Val, MID + 1, R, NUM << 1 | 1) \) .

So we can use the tree line quickly solved.


We take a closer look, modulus \ (29393 \) , the number of segments to be stored answer for each number less than or equal modulus.

Spatial complexity is \ (O (4 * n * modulus) \) , the time complexity is \ (O (n * log_n * modulus) \) .

Either can not afford the time or space.

Now, let's look at previously mentioned \ (29393 \) .

We break it down into \ (7 * 13 * 17 * 19 \) .

We found that, for these \ (4 \) number as the time and space complexity modulus are affordable.

Then let the current \ (X \) after this \ (4 \) answer modulo number is \ (res_i \) , the final answer is \ (Ans \) , we have:
\ [\ the begin {Cases} Ans = RES_1 \ % p_1 \\ Ans = res_2 \%
p_2 \\ Ans = res_3 \% p_3 \\ Ans = res_4 \% p_4 \ end {cases} \] we directly use the Chinese remainder Theorem to solve.

#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;
}

Guess you like

Origin www.cnblogs.com/dsjkafdsaf/p/11572887.html