求助卡常
查看原帖
求助卡常
404961
baiABCiBaraki545楼主2022/12/31 22:56

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;
}
``
2022/12/31 22:56
加载中...