莫隊水題一道,比Luogu P1494 [國家集訓隊]小Z的襪子還簡單的多git
先將詢問排個序,而後每次添加(刪除)元素的時候先前去以前的再更新後面的便可。spa
水題不想講,CODEcode
#include<cstdio> #include<cctype> #include<cmath> #include<algorithm> using namespace std; const int N=50005; struct data { int l,r,id; long long ans; }q[N]; int a[N],n,m,k,blk[N],size,L,R,cnt[N]; long long res; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void write(long long x) { if (x>9) write(x/10); putchar(x%10+'0'); } inline bool cmp1(data a,data b) { return blk[a.l]^blk[b.l]?(blk[a.l]<blk[b.l]):(blk[a.l]&1?a.r<b.r:a.r>b.r); } inline bool cmp2(data a,data b) { return a.id<b.id; } inline void add(int col) { res-=1LL*cnt[col]*cnt[col]; ++cnt[col]; res+=cnt[col]*cnt[col]; } inline void del(int col) { res-=1LL*cnt[col]*cnt[col]; --cnt[col]; res+=1LL*cnt[col]*cnt[col]; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i; read(n); read(m); read(k); size=sqrt(n); for (i=1;i<=n;++i) read(a[i]),blk[i]=(i-1)/size+1; for (i=1;i<=m;++i) read(q[i].l),read(q[i].r),q[i].id=i; sort(q+1,q+m+1,cmp1); L=q[1].l; R=q[1].r; for (i=L;i<=R;++i) add(a[i]); q[1].ans=res; for (i=2;i<=m;++i) { while (L>q[i].l) add(a[--L]); while (L<q[i].l) del(a[L++]); while (R<q[i].r) add(a[++R]); while (R>q[i].r) del(a[R--]); q[i].ans=res; } for (sort(q+1,q+m+1,cmp2),i=1;i<=m;++i) write(q[i].ans),putchar('\n'); return 0; }
這實際上是一道很好的練習主席樹的題目,不過因爲我比較懶不會,因此也就寫了莫隊。get
題目大意:給出\(n\)個數,求區間出現次數\(\ge2\)的數的個數。it
仍是莫隊啦,每次添加(刪除)時對於與\(2\)的大小關係特判一下便可,難度也很低。io
不過能夠只能拿原來數據的100分,後面的一個Subtask老實用主席樹吧class
CODE數據
#include<cstdio> #include<cctype> #include<cmath> #include<algorithm> using namespace std; const int N=300005; struct data { int l,r,id,ans; }q[N]; int a[N],n,m,k,blk[N],size,L,R,cnt[N]; long long res; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void write(int x) { if (x>9) write(x/10); putchar(x%10+'0'); } inline bool cmp1(data a,data b) { return blk[a.l]<blk[b.l]||(blk[a.l]==blk[b.l]&&(blk[a.l]&1?a.r<b.r:a.r>b.r)); } inline bool cmp2(data a,data b) { return a.id<b.id; } inline void add(int col) { if (++cnt[col]==2) ++res; } inline void del(int col) { if (--cnt[col]==1) --res; } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i; read(n); read(k); read(m); size=sqrt(n); for (i=1;i<=n;++i) read(a[i]),blk[i]=(i-1)/size+1; for (i=1;i<=m;++i) read(q[i].l),read(q[i].r),q[i].id=i; sort(q+1,q+m+1,cmp1); L=q[1].l; R=q[1].r; for (i=L;i<=R;++i) add(a[i]); q[1].ans=res; for (i=2;i<=m;++i) { while (L>q[i].l) add(a[--L]); while (L<q[i].l) del(a[L++]); while (R<q[i].r) add(a[++R]); while (R>q[i].r) del(a[R--]); q[i].ans=res; } for (sort(q+1,q+m+1,cmp2),i=1;i<=m;++i) write(q[i].ans),putchar('\n'); return 0; }