NOIP模拟赛 czy的后宫3
【题目描述】
上次czy在机房妥善安排了他的后宫之后,他发现可以将他的妹子分为c种,他经常会考虑这样一个问题:在[l,r]的妹子中间,能挑选出多少不同类型的妹子呢?
注意:由于czy非常丧尸,所以他要求在所挑选的妹子类型在[l,r]中出现次数为正偶数,你懂得。
问题简述:n个数,m次询问,每次问[l,r]区间有多少个数恰好出现正偶数次
【输入格式】
第一行3个整数,表示n,c,m
第二行n个数,每个数Ai在[1,c]之间,表示一个Ai类型的妹子
接下来m行,每行两个整数l,r,表示询问[l,r]这个区间的答案
【输出格式】
有m行,表示第i次询问的答案
【样例输入】
5 5 3
1 1 2 2 3
1 5
3 4
2 3
【样例输出】
2
1
0
【数据范围】
共有10组测试数据
1-4组n,m=500,2000,5000,10000,c=1000
5-7组n,m=20000,30000,40000,c=10000
8-10组n,m=50000,80000,100000,c=100000
数据保证随机生成
同小z的袜子
1 #define LL long long 2 3 #include<iostream> 4 #include<cstdio> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 10 const int MAXN=100000+10; 11 12 struct qnode 13 { 14 int l,r,id; 15 }qu[MAXN]; 16 17 int n,c,m,block; 18 int a[MAXN],pos[MAXN]; 19 LL num[MAXN],ans[MAXN],temp; 20 21 int read() 22 { 23 int x=0,f=1;char ch=getchar(); 24 while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} 25 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 26 return x*f; 27 } 28 29 bool cmp(qnode a,qnode b) 30 { 31 if(pos[a.l]==pos[b.l]) 32 return a.r<b.r; 33 return pos[a.l]<pos[b.l]; 34 } 35 36 void update(int x,int d) 37 { 38 int t=num[a[x]]; 39 num[a[x]]+=d; 40 if(t%2==1&&num[a[x]]%2==0&&num[a[x]]>0) temp++; 41 if(t%2==0&&num[a[x]]%2==1&&t>0) temp--; 42 } 43 44 int main() 45 { 46 n=read();c=read();m=read(); 47 block=(int)sqrt(n); 48 for(int i=1;i<=n;i++) 49 { 50 a[i]=read(); 51 pos[i]=(i-1)/block+1; 52 } 53 for(int i=1;i<=m;i++) 54 { 55 qu[i].l=read();qu[i].r=read(); 56 qu[i].id=i; 57 } 58 sort(qu+1,qu+m+1,cmp); 59 60 int pl=1,pr=0,id; 61 for(int i=1;i<=m;i++) 62 { 63 id=qu[i].id; 64 if(qu[i].l==qu[i].r) 65 { 66 ans[id]=0; 67 continue; 68 } 69 if(pr<qu[i].r) 70 for(int j=pr+1;j<=qu[i].r;j++) 71 update(j,1); 72 else 73 for(int j=pr;j>qu[i].r;j--) 74 update(j,-1); 75 pr=qu[i].r; 76 if(pl<qu[i].l) 77 for(int j=pl;j<qu[i].l;j++) 78 update(j,-1); 79 else 80 for(int j=pl-1;j>=qu[i].l;j--) 81 update(j,1); 82 pl=qu[i].l; 83 ans[id]=temp; 84 } 85 for(int i=1;i<=m;i++) 86 cout<<ans[i]<<endl; 87 return 0; 88 }