1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| inline void del(int p,int val){ shownc[p][val]--; } inline void add(int p,int val){ shownc[p][val]++; }
inline void unpag(int bk,vector<int> &s){ s.clear(); while(que[bk].size()) s.push_back(que[bk].front()),que[bk].pop(); } inline void addpag(vector<int> &s,int bk){ for(int i=0;i<s.size();++i) que[bk].push(s[i]); }
vector<int> _this; void inblock_update(int l,int r,int in){ unpag(in,_this); int lpos=bk[in].len-inbkpos[l],rpos=bk[in].len-inbkpos[r]; int x=_this[rpos]; for(int i=rpos;i<lpos;++i){ _this[i]=_this[i+1]; } _this[lpos]=x; addpag(_this,in); }
vector<int> front,back; void update(int l,int r){ int lin=inbk[l],rin=inbk[r]; if(lin==rin){ inblock_update(l,r,lin); return; } unpag(lin,front); unpag(rin,back); int lpos=bk[lin].len-inbkpos[l],rpos=bk[rin].len-inbkpos[r];
int x=front[0]; for(int i=0;i<lpos;++i){ front[i]=front[i+1]; } front[lpos]=back[rpos]; del(lin,x); add(lin,back[rpos]);
for(int i=lin+1;i<=rin-1;++i){ que[i].push(x); add(i,x); x=que[i].front(); del(i,x); que[i].pop(); }
del(rin,back[rpos]); for(int i=rpos;i<back.size()-1;++i){ back[i]=back[i+1]; } back[back.size()-1]=x; add(rin,x); addpag(front,lin); addpag(back,rin); }
ll inblock_query(int l,int r,int in,ll k){ ll res=0; unpag(in,_this); int lpos=bk[in].len-inbkpos[l],rpos=bk[in].len-inbkpos[r]; for(int i=rpos;i<=lpos;++i){ if(_this[i]==k) ++res; } addpag(_this,in); return res; }
ll query(int l,int r,ll k){ int lin=inbk[l],rin=inbk[r]; if(lin==rin){ return inblock_query(l,r,lin,k); } ll res=0; unpag(lin,front); unpag(rin,back);
int lpos=bk[lin].len-inbkpos[l],rpos=bk[rin].len-inbkpos[r];
for(int i=0;i<=lpos;++i) if(front[i]==k) ++res; for(int i=rpos;i<back.size();++i) if(back[i]==k) ++res;
for(int i=lin+1;i<=rin-1;++i){ res+=shownc[i][k]; } addpag(front,lin); addpag(back,rin); return res; }
|