Make complaints
Let the practice card of \ (nlog \) pass..
thinking
Because \ (1 \le q \le 10^5 \), you can first label the position of each standard operation. In this way, all subscripts are within \ (10 ^ 5 \).
Both multiply and add operations can be written in the form of \ (kx+b \). A prefix is then maintained for these operations. Then you can get an operation in a range.
Interval query we just need to find a \ (TOT \) to maintain all the current elements and.
Single point query, observe the time of the last assignment. If it is earlier than the collective assignment, most of the current values are output.
Otherwise, the last assigned value is multiplied by the operation from the last assigned value to the current time point.
Code
/* * @Author: wxyww * @Date: 2019-05-07 20:58:04 * @Last Modified time: 2019-05-11 10:33:03 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<ctime> #include<map> using namespace std; typedef long long ll; const int N = 100010,mod = 1e7 + 19; map<int,int>ma; ll read() { ll x=0,f=1;char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } struct node { int opt,pos,val; }que[N]; int TOT,s[N],a[N],b[N],now,inv[mod + 1],n,T,Q,mul[N * 100],add[N * 100]; int lst[N],LAST; int query(int x,int num) { if(lst[x] <= LAST) return now; int cheng = 1ll * mul[num] * inv[mul[lst[x]]] % mod; int jia = (add[num] - 1ll * add[lst[x] - 1] * cheng % mod + mod) % mod; return (1ll * s[x] * cheng % mod + jia) % mod; } int ans; void solve(int x,int num) { int opt = que[x].opt,pos = que[x].pos,val = que[x].val % mod; mul[num] = mul[num - 1],add[num] = add[num - 1]; if(opt == 1) { TOT -= query(pos,num); TOT += val; TOT = (TOT % mod + mod) % mod; lst[pos] = num; s[pos] = val; } else if(opt == 2) { TOT += (1ll * n * val % mod + mod) % mod; TOT = (TOT % mod + mod) % mod; add[num] += val; add[num] = (add[num] %mod + mod) % mod; now += val; now = (now % mod + mod) % mod; } else if(opt == 3) { TOT = (1ll * TOT * val % mod + mod) % mod; now = (1ll * now * val % mod + mod) % mod; add[num] = (1ll * add[num] * val % mod + mod) % mod; mul[num] = (1ll * mul[num] * val % mod + mod) % mod; } else if(opt == 4) { TOT = (1ll * val * n % mod + mod) % mod; mul[num] = 1;add[num] = 0; now = val; LAST = num; } else if(opt == 5) ans += query(pos,num),ans = (ans % mod + mod) % mod; else ans = ((ans + TOT) % mod + mod) % mod; } int main() { n = read(),Q = read(); for(int i = 1;i <= Q;++i) { int opt = que[i].opt = read(); if(opt == 1) { que[i].pos = read();que[i].val = read(); } else if(opt == 6) continue; else if(opt == 5) que[i].pos = read(); else que[i].val = read(); } inv[1] = 1; for(int i = 2;i < mod;++i) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod; int js = 0; for(int i = 1;i <= Q;++i) { if(!que[i].pos) continue; if(!ma[que[i].pos]) ma[que[i].pos] = ++js; que[i].pos = ma[que[i].pos]; } int T = read(),num = 0; for(int i = 1;i <= T;++i) a[i] = read(),b[i] = read(); for(int i = 1;i <= T;++i) for(int j = 1;j <= Q;++j) solve((a[i] + 1ll * j * b[i] % Q) % Q + 1,++num); cout<<(ans % mod + mod) % mod; return 0; }