BC的官方题解已经写的很清楚了。。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 50005 #define maxm 400005 #define eps 1e-10 //#define mod 2333333 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R //#pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b, LL mod){LL res=1%mod,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head int mo[20] = {2333333,2196720,580608,165888,55296,18432,6144,2048,1024,512,256,128,64,32,16,8,4,2,1}; LL pow2[33]; vector<LL> v[maxn]; LL sum[maxn << 2]; LL add[maxn << 2]; LL a[maxn]; int n, m; const int MOD = 2333333; void read(void) { pow2[0] = 1; for(int i = 1; i <= 30; i++) pow2[i] = pow2[i-1] * 2; for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]); } void pushup(int o); void build(int o, int L, int R) { add[o] = 0; if(L == R) { sum[o] = a[L]; v[L].clear(); v[L].push_back(a[L]); return; } int mid = (L + R) >> 1; build(lson); build(rson); pushup(o); } void pushup(int o) { sum[o] = (sum[ls] + sum[rs]) % MOD; } void pushdown(int o, int L, int R) { if(add[o]) { int mid = (L + R) >> 1; sum[ls] = (sum[ls] + add[o] * (mid - L + 1) % MOD) % MOD; sum[rs] = (sum[rs] + add[o] * (R - mid) % MOD) % MOD; add[ls] += add[o]; add[rs] += add[o]; add[o] = 0; } } LL query(int o, int L, int R, int ql, int qr) { if(ql <= L && qr >= R) return sum[o]; pushdown(o, L, R); int mid = (L + R) >> 1; LL ans = 0; if(ql <= mid) ans = (ans + query(lson, ql, qr)) % MOD; if(qr > mid) ans = (ans + query(rson, ql, qr)) % MOD; pushup(o); return ans; } void update(int o, int L, int R, int ql, int qr, LL x) { if(ql <= L && qr >= R) { sum[o] = ((R - L + 1) * x % MOD + sum[o]) % MOD; add[o] += x; return; } pushdown(o, L, R); int mid = (L + R) >> 1; if(ql <= mid) update(lson, ql, qr, x); if(qr > mid) update(rson, ql, qr, x); pushup(o); } LL calc(vector<LL> &vec) { if(vec.size() > 18) { LL res = 1; int now = 18; for(int i = vec.size() - 18; i < vec.size(); i++) { res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now]; now--; } return res % MOD; } else { LL res = vec[0]; int now = vec.size() - 1; int flag = 0; if(res >= mo[now]) { flag = 1; res = res % mo[now] + mo[now]; } now--; for(int i = 1; i < vec.size(); i++) { if(flag) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now]; else if(res >= 30) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now], flag = 1; else if(pow2[res] >= mo[now]) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now], flag = 1; else { res = pow2[res] + vec[i]; if(res >= mo[now]) { flag = 1; res = res % mo[now] + mo[now]; } } now--; } return res % MOD; } } void modify(int o, int L, int R, LL x) { if(L == R) { if(add[o]) { v[L][v[L].size() - 1] += add[o]; add[o] = 0; } v[L].push_back(0); sum[o] = calc(v[L]); return; } pushdown(o, L, R); LL mid = (L + R) >> 1; if(x <= mid) modify(lson, x); else modify(rson, x); pushup(o); } void work(void) { int ql, qr, k; LL x; build(1, 1, n); while(m--) { scanf("%d", &k); if(k == 1) { scanf("%d%d", &ql, &qr); printf("%I64d\n", query(1, 1, n, ql, qr)); } if(k == 2) { scanf("%I64d", &x); modify(1, 1, n, x); } if(k == 3) { scanf("%d%d%I64d", &ql, &qr, &x); update(1, 1, n, ql, qr, x); } } } int main(void) { while(scanf("%d%d", &n, &m)!=EOF) { read(); work(); } return 0; }