bzoj 1878: [SDOI2009]HH的項鏈【樹狀數組】
阿新 • • 發佈:2018-07-29
當前 ostream return spa \n sort 排序 升序 一個
對於一個lr,每個顏色貢獻的是在(1,r)區間裏出現的最右位置,所以記錄一個b數組表示當前點這個顏色上一個出現的位置
然後把詢問離線,按r升序排序
每次把右端點右移,把這個點在樹狀數組上+1,並且在當前這個點的b位置上-1(表示沒用了),然後樹狀數組前綴和減一下即可
我寫的莫隊會T
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=1000005; int n,m,a[N],b[N],la[N],t[N],ans[N]; struct qwe { int l,r,id; }q[N]; bool cmp(const qwe &a,const qwe &b) { return a.r<b.r; } int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void update(int x,int w) { if(x==0) return; for(int i=x;i<=n;i+=(i&(-i))) t[i]+=w; } int ques(int x) { int r=0; for(int i=x;i>=1;i-=(i&(-i))) r+=t[i]; return r; } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(),b[i]=la[a[i]],la[a[i]]=i; m=read(); for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; sort(q+1,q+1+m,cmp); int r=0; for(int i=1;i<=m;i++) { while(r<q[i].r) r++,update(b[r],-1),update(r,1); ans[q[i].id]=ques(q[i].r)-ques(q[i].l-1); } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }
bzoj 1878: [SDOI2009]HH的項鏈【樹狀數組】