[bzoj 2120]數顏色
阿新 • • 發佈:2018-12-24
傳送門
Description
墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會像你釋出如下指令: 1、 Q L R代表詢問你從第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。 2、 R P Col 把第P支畫筆替換為顏色Col。為了滿足墨墨的要求,你知道你需要幹什麼了嗎?
Solution
這是帶修改的莫隊
排序方式:按照
pos[l]
為第一關鍵字,pos[r]
為第二關鍵字,時間為第三關鍵字修改可以看作是一次插入和一次刪除
而撤銷修改同樣也是一次修改和一次刪除
設T是一塊的長度
- 修改操作的維護,或者說是時間軸的移動,複雜度是\(O(\frac{n^3}{T^2})\)
的- 很顯然,l,r的移動,複雜度是\(O(\frac{n^2}{T})+O(nT)\)
當\(T=n^{\frac{2}{3}}\)時,複雜度最優,為\(O(n^{\frac{3}{5}})\).
Code
#include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } #define MN 50005 int N,M,T,a[MN],pos[MN],totq,totu; struct QUE{int l,r,t,id,ans;}q[MN]; struct UPD{int fr,to,x;}u[MN]; int ans; inline bool cmp(const QUE&o,const QUE&oo) {return (pos[o.l]^pos[oo.l])?(pos[o.l]<pos[oo.l]):((pos[o.r]^pos[oo.r])?(pos[o.r]<pos[oo.r]):(o.t<oo.t));} int num[1000005]; inline bool cmp2(const QUE&o,const QUE&oo){return o.id<oo.id;} int main() { N=read();M=read(); register int i,x; register char ch[10];T=1357; for(i=1;i<=N;++i) a[i]=read(),pos[i]=(i-1)/T+1; for(i=1;i<=M;++i) { scanf("%s",ch+1); if(ch[1]=='Q') { q[++totq].l=read(),q[totq].r=read(); q[totq].id=totq;q[totq].t=totu; } else { u[++totu].x=read(),u[totu].to=read(); u[totu].fr=a[u[totu].x];a[u[totu].x]=u[totu].to; } } for(i=totu;i;--i) a[u[i].x]=u[i].fr; std::sort(q+1,q+totq+1,cmp); register int j=0,l=1,r=0,ans=0; for(i=1;i<=totq;++i) { for(;l>q[i].l;--l) ans+=!(num[a[l-1]]++); for(;l<q[i].l;++l) ans-=!(--num[a[l]]); for(;r<q[i].r;++r) ans+=!(num[a[r+1]]++); for(;r>q[i].r;--r) ans-=!(--num[a[r]]); for(;j<q[i].t;++j) { a[u[j+1].x]=u[j+1].to; if(u[j+1].x<=q[i].r&&u[j+1].x>=q[i].l) ans-=!(--num[u[j+1].fr]),ans+=!(num[u[j+1].to]++); } for(;j>q[i].t;--j) { a[u[j].x]=u[j].fr; if(u[j].x<=q[i].r&&u[j].x>=q[i].l) ans+=!(num[u[j].fr]++),ans-=!(--num[u[j].to]); } q[i].ans=ans; } std::sort(q+1,q+totq+1,cmp2); for(i=1;i<=totq;++i) printf("%d\n",q[i].ans); }
Blog來自PaperCloud,未經允許,請勿轉載,TKS!