RT,主要是 op1 常数过大,sub4 有一半点 TLE
复杂度应该没有问题 /kel
#include <bits/stdc++.h>
#define int unsigned int
using namespace std;
#define EOL putchar('\n')
#define END exit(0)
void rd(int &x)
{
int ch; x = 0;
while(isspace(ch=getchar()));
if(ch == EOF) return;
do x = ch-'0'+x*10; while(isdigit(ch=getchar()));
}
void pt(long long x)
{
if(x>9)pt(x/10);
putchar(x%10+'0');
}
//#define Dn(x) Dn[x]
#define Dn(x) (1<<(6*((x)-1)))
#define ls (u<<1)
#define rs (u<<1|1)
#define INF 0x3f3f3f3f
#define tolo const int&
const int base = 64, maxn = 500000, SZ = maxn/30, CN=floor(log(1e9)/log(base)+1);
int cnt_block = floor(log(1e9)/log(base)+1), UP = 1000000000;
int fk_L[SZ+1], fk_R[SZ+1], fk_id[maxn+3], N, a[maxn+3], fk_ID[maxn+3];
int Dn[CN+2];
int n, m;
//bool ned[CN+1];
struct Node {
int mx, mn, tg, len;
long long s;
} t[CN+2][SZ*4+1];
int revid[SZ+1];
int Cnt[CN+2];
void init()
{/*
Dn[1] = 1;
for(int i = 2; i <= cnt_block; ++i) Dn[i] = Dn[i-1]*base;*/
int len = (n-1)/SZ+1;
fk_L[1] = 1; fk_R[1] = len; N = 1;
while(fk_R[N] < n)
{
fk_L[N+1] = fk_R[N]+1;
fk_R[N+1] = min(fk_R[N]+len, n);
++N;
}
for(int i = 1; i <= N; ++i)
{
for(int j = fk_L[i]; j <= fk_R[i]; ++j)
fk_id[j] = i;
}
}
//#define ID(x) (upper_bound(Dn+1, Dn+cnt_block+1, (x))-(Dn+1))
#define ID(x) (__lg((x))/6+1)
inline Node pushup(const Node &a, const Node &b)
{
Node ans;
if(a.mx > b.mx) ans.mx = a.mx;
else ans.mx = b.mx;
if(a.mn < b.mn) ans.mn = a.mn;
else ans.mn = b.mn;
ans.s = a.s+b.s;
ans.tg = 0;
ans.len = a.len + b.len;
return ans;
}
void build(tolo u, tolo l, tolo r)
{
if(l == r)
{
revid[l] = u;
for(int i = 1; i <= cnt_block; ++i)
t[i][u].mn = INF;
for(int i = fk_L[l]; i <= fk_R[l]; ++i)
{
rd(a[i]);
Node &o = t[fk_ID[i]=ID(a[i])][u];
++Cnt[fk_ID[i]];
if(a[i] > o.mx) o.mx = a[i];
if(a[i] < o.mn) o.mn = a[i];
++o.len; o.s += a[i];
}
return;
}
int mid = l+r>>1; build(ls, l, mid); build(rs, mid+1, r);
for(int i = 1; i <= cnt_block; ++i)
t[i][u] = pushup(t[i][ls], t[i][rs]);
}
inline void maketag(tolo i, tolo u, tolo x)
{
if(t[i][u].mx) t[i][u].mx -= x, t[i][u].mn -= x,
t[i][u].s -= 1ll*t[i][u].len*x, t[i][u].tg += x;
}
inline void pushdown(tolo i, tolo u)
{
maketag(i, ls, t[i][u].tg);
maketag(i, rs, t[i][u].tg);
t[i][u].tg = 0;
}
void change(tolo i, tolo u, tolo l, tolo r, tolo L, tolo R, tolo x)
{
if(L <= l && r <= R) {maketag(i, u, x); return;}
int mid = l+r>>1; pushdown(i, u);
if(L <= mid) change(i, ls, l, mid, L, R, x);
if(mid < R) change(i, rs, mid+1, r, L, R, x);
t[i][u] = pushup(t[i][ls], t[i][rs]);
}
Node query(tolo i, tolo u, tolo l, tolo r, tolo L, tolo R)
{
if(L <= l && r <= R) return t[i][u];
int mid = l+r>>1; pushdown(i, u);
if(L <= mid)
if(mid < R)
return pushup(query(i,ls,l,mid,L,R),query(i,rs,mid+1,r,L,R));
else
return query(i,ls,l,mid,L,R);
return query(i,rs,mid+1,r,L,R);
}
int st[maxn+5], tp;
inline void pushtag(int id, tolo u)
{
//if(!ned[id]) return;
for(int i = revid[u]>>1; i; i >>= 1) st[++tp] = i;
while(tp) pushdown(id, st[tp--]);
if(!t[id][revid[u]].tg) return;
for(int i = fk_L[u]; i <= fk_R[u]; ++i)
if(!(fk_ID[i] ^ id)) a[i] -= t[id][revid[u]].tg;
t[id][revid[u]].tg = 0;
}
inline Node fk_ask(tolo u, tolo l, tolo r)
{
for(int i = revid[u]>>1; i; i >>= 1) st[++tp] = i;
for(;tp;--tp)
for(int I = 1; I <= cnt_block; ++I)
pushdown(I, st[tp]);
for(int i = fk_L[u]; i <= fk_R[u]; ++i)
if(a[i]) a[i] -= t[fk_ID[i]][revid[u]].tg;
for(int i = 1; i <= cnt_block; ++i)
t[i][revid[u]].tg = 0;
Node ans; ans.mn = INF;
ans.mx = ans.s = ans.tg = 0;
for(int i = l; i <= r; ++i)
if(fk_ID[i])
{
if(a[i] < ans.mn) ans.mn = a[i];
if(a[i] > ans.mx) ans.mx = a[i];
ans.s += a[i]; ++ans.len;
}
return ans;
}
inline Node ask(tolo l, tolo r)
{
Node ans; ans.mn = INF; ans.mx = 0; ans.s = 0;
if(!(fk_id[l] ^ fk_id[r])) return fk_ask(fk_id[l], l, r);
ans = fk_ask(fk_id[l], l, fk_R[fk_id[l]]);
ans = pushup(ans, fk_ask(fk_id[r], fk_L[fk_id[r]], r));
if(fk_id[l]+1 <= fk_id[r]-1)
for(int i = 1; i <= cnt_block; ++i)
ans = pushup(ans, query(i, 1, 1, N, fk_id[l]+1, fk_id[r]-1));
return ans;
}
inline void inchg(tolo id, tolo u, tolo l, tolo r, tolo x)
{
pushtag(id, u);
Node &o = t[id][revid[u]];
o.mx = o.s = 0;
o.mn = INF;
for(int i = fk_L[u]; i <= fk_R[u]; ++i)
if(!(fk_ID[i] ^ id))
{
if(l <= i && i <= r) a[i] -= x;//,cout<<"?"<<'\n';
if(a[i] > o.mx) o.mx = a[i];
if(a[i] < o.mn) o.mn = a[i];
o.s += a[i];
}
for(int i = revid[u]>>1; i; i >>= 1)
t[id][i] = pushup(t[id][i<<1], t[id][i<<1|1]);
}
inline void fk_change(tolo id, tolo l, tolo r, tolo x)
{//cout<<"fk_change "<<id<<' '<<l<<' '<<r<<' '<<x<<'\n';
if(!(fk_id[l] ^ fk_id[r])) {inchg(id, fk_id[l], l, r, x); return;}
inchg(id, fk_id[l], l, fk_R[fk_id[l]], x);
inchg(id, fk_id[r], fk_L[fk_id[r]], r, x);
if(fk_id[l]+1 <= fk_id[r]-1) /*ned[id] = true, */change(id, 1, 1, N, fk_id[l]+1, fk_id[r]-1, x);
}
int v1[maxn+5], v2[maxn+5], tpp;
void indel(tolo id, tolo u, tolo l, tolo r, tolo L, tolo R)
{//cout<<"indel " <<id<<' '<<u<<' '<<l<<' '<<r<<' '<<L<<' '<<R<<'\n';
pushtag(id, u);
Node &o = t[id][revid[u]];
o.mx = o.s = o.len = 0;
o.mn = INF;
for(int i = fk_L[u]; i <= fk_R[u]; ++i)
if(!(fk_ID[i] ^ id))
{
if((l <= i) & (i <= r) & ((a[i] < L) | (a[i] > R)))
{
v1[tpp] = i; v2[tpp] = a[i]; ++tpp;
a[i] = 0; fk_ID[i] = 0;
}
else
{
++o.len; o.s += a[i];
o.mx = max(o.mx, a[i]);
o.mn = min(o.mn, a[i]);
}
}
for(int i = revid[u]>>1; i; i >>= 1)
t[id][i] = pushup(t[id][i<<1], t[id][i<<1|1]);
}
void mydel(tolo i, tolo u, tolo l, tolo r, tolo lr, tolo rr, tolo L, tolo R)
{//cout<<i<<' '<<u<<' '<<l<<' '<<r<<' '<<lr<<' '<<rr<<' '<<L<<' '<<R<<'\n';
if(l == r) {indel(i, l, fk_L[l], fk_R[r], L, R); return;}
int mid = l+r>>1; pushdown(i, u);
if(lr <= l && r <= rr)
{
if((t[i][ls].mn < L) | (t[i][ls].mx > R)) mydel(i, ls, l, mid, lr, rr, L, R);
if((t[i][rs].mn < L) | (t[i][rs].mx > R)) mydel(i, rs, mid+1, r, lr, rr, L, R);
}
else
{
if(lr <= mid) mydel(i, ls, l, mid, lr, rr, L, R);
if(mid < rr) mydel(i, rs, mid+1, r, lr, rr, L, R);
}
t[i][u] = pushup(t[i][ls], t[i][rs]);
}
inline void fk_del(tolo id, tolo l, tolo r, tolo L, tolo R)
{//cout<<"fk_del "<<id<<' '<<l<<' '<<r<<' '<<L<<' '<<R<<'\n';
if(fk_id[l] ^ fk_id[r])
{
indel(id, fk_id[l], l, fk_R[fk_id[l]], L, R);
indel(id, fk_id[r], fk_L[fk_id[r]], r, L, R);
if(fk_id[l]+1 <= fk_id[r]-1) mydel(id, 1, 1, N, fk_id[l]+1, fk_id[r]-1, L, R);
}else indel(id, fk_id[l], l, r, L, R);
Cnt[id] -= tpp;
}
inline void myadd(tolo i, tolo k, tolo x)
{
pushtag(i, fk_id[k]);
int uu = fk_id[k];
Node &o = t[i][revid[uu]]; ++o.len;
o.mx = o.s = 0; o.mn = INF;
a[k] = x; fk_ID[k] = i;
for(int j = fk_L[uu]; j <= fk_R[uu]; ++j)
if(!(fk_ID[j] ^ i))
{
if(a[j] > o.mx) o.mx = a[j];
if(a[j] < o.mn) o.mn = a[j];
o.s += a[j];
}
int id = i;
for(int i = revid[uu]>>1; i; i >>= 1)
t[id][i] = pushup(t[id][i<<1], t[id][i<<1|1]);
++Cnt[id];
}
inline void modify(tolo l, tolo r, tolo x)
{
int id = ID(x);
tpp = 0;
if(Cnt[id])
{
fk_del(id, l, r, 1, x);
for(int i = 0; i < tpp; ++i)
myadd(ID(v2[i]-x), v1[i], v2[i]-x);
}
tpp = 0;
for(int i = id+1; i <= cnt_block; ++i)
if(Cnt[i])
{
fk_change(i, l, r, x);
fk_del(i, l, r, Dn(i), UP);
}
for(int i = 0; i < tpp; ++i)
myadd(ID(v2[i]), v1[i], v2[i]);
}
signed main()
{
//ios::sync_with_stdio(0);
rd(n); rd(m);
init();
build(1, 1, N);
while(!Cnt[cnt_block]) UP=Dn(cnt_block--)-1;
int lastans = 0;
while(m--)
{
int op, l, r; rd(op); rd(l); rd(r);
l ^= lastans; r ^= lastans;
if(op&1) {int x; cin >> x; modify(l, r, x^lastans);}
else
{
Node ans = ask(l, r);
pt(ans.s); putchar(' '); pt(ans.mn); putchar(' '); pt(ans.mx); EOL;
lastans = ans.s&0xfffff;
}
while(!Cnt[cnt_block]) UP=Dn(cnt_block--)-1;
//print();
}
END;
}
``