您正在打galgame,而後忽然發現您今天太頹了,因而想寫個數據結構題練練手:html
給出一個長爲 nnn 的序列 aaa。node
有 mmm 個詢問,每次詢問三個區間,把三個區間中同時出現的數一個一個刪掉,問最後三個區間剩下的數的個數和,詢問獨立。ios
注意這裏刪掉指的是一個一個刪,不是把等於這個值的數直接刪完,好比三個區間是 [1,2,2,3,3,3,3][1,2,2,3,3,3,3][1,2,2,3,3,3,3] , [1,2,2,3,3,3,3][1,2,2,3,3,3,3][1,2,2,3,3,3,3] 與 [1,1,2,3,3][1,1,2,3,3][1,1,2,3,3],就一塊兒扔掉了 111 個 111,111 個 222,222 個 333。數據結構
第一行兩個數表示 nnn , mmm。ui
第二行 nnn個數表示 aia_iai。spa
以後 mmm 行,每行 666 個數 l1l_1l1 , r1r_1r1 , l2l_2l2 , r2r_2r2 , l3l_3l3 , r3r_3r3 表示這三個區間。code
對於每一個詢問,輸出一個數表示答案。htm
5 2 1 2 2 3 3 1 2 2 3 3 4 1 5 1 5 1 5
3 0
1≤n,m≤1051 \leq n,m \leq 10^{5}1≤n,m≤105 , 1≤ai≤1091 \leq a_i \leq 10^{9}1≤ai≤109blog
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #include<cmath> #define maxn 100010 using namespace std; int n,a[maxn],b[maxn],cnt[maxn],pos[maxn],block,tot,ans[maxn],T=25000; bool mark[maxn]; struct node{int l,r,id;}q[maxn]; bitset<100000>F[25001],f; bool cmp(node a,node b){ if(pos[a.l]==pos[b.l])return a.r<b.r; return pos[a.l]<pos[b.l]; } void update(int k,int ty){ k=a[k];cnt[k]+=ty; if(ty==1)f[k+cnt[k]-2]=1; else f[k+cnt[k]-1]=0; } void solve(int m){ int L,R,l1,l2,l3,r1,r2,r3; memset(cnt,0,sizeof(cnt)); memset(mark,0,sizeof(mark)); f.reset();tot=0; for(int i=1;i<=m;i++){ scanf("%d%d%d%d%d%d",&l1,&r1,&l2,&r2,&l3,&r3); q[++tot]=(node){l1,r1,i}; q[++tot]=(node){l2,r2,i}; q[++tot]=(node){l3,r3,i}; ans[i]=r3+r2+r1-l3-l2-l1+3; } sort(q+1,q+tot+1,cmp); L=1;R=0; for(int i=1;i<=tot;i++){ while(R<q[i].r)update(++R,1); while(R>q[i].r)update(R--,-1); while(L<q[i].l)update(L++,-1); while(L>q[i].l)update(--L,1); if(mark[q[i].id])F[q[i].id]&=f; else F[q[i].id]=f,mark[q[i].id]=1; } for(int i=1;i<=m;i++){ int k=F[i].count(); printf("%d\n",ans[i]-3*k); } } int main(){ int m; scanf("%d%d",&n,&m); block=sqrt(n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; pos[i]=(i-1)/block+1; } sort(b+1,b+n+1); for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b; while(m){ if(m<=T)solve(m),m=0; else solve(T),m-=T; } return 0; }