具体见代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+10; 5 const int mod=1e9+7; 6 #define rep(i,first,second) for(int i=first;i<=second;i++) 7 #define dep(i,first,second) for(int i=first;i>=second;i--) 8 9 struct node{//右端点大的优先 10 int l,r,id; 11 bool operator < (const node &a) const{ 12 if( r==a.r ) return l<a.l; 13 return r>a.r; 14 } 15 }s[maxn]; 16 17 int n,m,a[maxn]; 18 int first[maxn];//记录从前往后不同数的个数 19 int vis[maxn]; 20 int sum[maxn]; 21 int lowbit(int x){ return x&-x;} 22 void update(int pos,int val){ 23 while( pos<=n ){ 24 sum[pos]+=val; 25 pos+=lowbit(pos); 26 } 27 } 28 int query(int pos){ 29 int ans=0; 30 while( pos>0 ){ 31 ans+=sum[pos]; 32 pos-=lowbit(pos); 33 } 34 return ans; 35 } 36 int pre[maxn],ans[maxn]; 37 int main() 38 { 39 while( ~scanf("%d%d",&n,&m)){ 40 memset(first,0,sizeof(first)); 41 int res=0;//记录从后往前不同数的个数 42 rep(i,1,n){ 43 scanf("%d",&a[i]); 44 if( !first[a[i]] ){ 45 first[a[i]]=i; 46 res++; 47 } 48 pre[i]=res;//记下i位置前面不同数的个数 49 } 50 rep(i,1,m){ 51 scanf("%d%d",&s[i].l,&s[i].r); 52 s[i].id=i; 53 } 54 sort(s+1,s+1+m); 55 memset(sum,0,sizeof(sum)); 56 memset(vis,0,sizeof(vis)); 57 res=0;//记录从后往前不同数的个数 58 int r=n+1; 59 rep(i,1,m){ 60 while( r>s[i].r ){ 61 r--; 62 if( !vis[a[r]]){ 63 res++; 64 vis[a[r]]=1; 65 update(first[a[r]],1); 66 } 67 } 68 ans[s[i].id]=pre[s[i].l]+res-query(s[i].l);//s[i].l以前不同的个数+res-前后重复出现的数量 69 } 70 rep(i,1,m) printf("%d ",ans[i]); 71 } 72 return 0; 73 }
Mishka and Interesting sum
分析:每一次询问的答案,等于 这个区间所有不同元素异或和 异或上 区间异或和。(因为出现偶数次的对区间异或和贡献为0,此时剩下的是出现奇数次的数,在取个补集即为答案);x^x=0,x^0=x;
1 //每一次询问的答案,等于 这个区间所有不同元素异或和 异或上 区间异或和。(因为出现偶数次的对区间异或和贡献为0,此时剩下的是出现奇数次的数,在取个补集即为答案) 2 //x^x=0,x^0=x; 3 #include <bits/stdc++.h> 4 using namespace std; 5 typedef long long ll; 6 const int maxn=1e6+10; 7 const int mod=1e9+7; 8 #define rep(i,first,second) for(int i=first;i<=second;i++) 9 #define dep(i,first,second) for(int i=first;i>=second;i--) 10 11 struct node{ 12 int id,l,r; 13 bool operator < (const node &a) const{ 14 return r<a.r; 15 } 16 }e[maxn]; 17 18 int tree[maxn],sum[maxn],a[maxn]; 19 map<int,int>vis; 20 int n,ans[maxn],m; 21 22 int lowbit(int x){ return x&(-x);} 23 void update(int pos,int val){ 24 while( pos<=n ){ 25 tree[pos]^=val; 26 pos+=lowbit(pos); 27 } 28 } 29 int query(int x){ 30 int res=0; 31 while( x ){ 32 res^=tree[x]; 33 x-=lowbit(x); 34 } 35 return res; 36 } 37 38 int main() 39 { 40 scanf("%d",&n); 41 rep(i,1,n){ 42 scanf("%d",&a[i]); 43 sum[i]=sum[i-1]^a[i]; 44 } 45 scanf("%d",&m); 46 rep(i,1,m){ 47 scanf("%d%d",&e[i].l,&e[i].r); 48 e[i].id=i; 49 } 50 sort(e+1,e+1+m); 51 52 int p=1; 53 rep(i,1,m){ 54 int l=e[i].l,r=e[i].r; 55 while( p<=r ){ 56 if( !vis[a[p]] ){//第一次出现 57 vis[a[p]]=p;//记录位置 58 update(p,a[p]); 59 } 60 else{ 61 update(vis[a[p]],a[p]);//在现区间出现过,则原位置清零 62 update(p,a[p]); 63 vis[a[p]]=p; 64 } 65 p++; 66 } 67 ans[e[i].id]=sum[r]^sum[l-1]^query(r)^query(l-1);//在现区间没有出现过的数通过query(r)^query(l-1)清零 68 } 69 rep(i,1,m) printf("%d ",ans[i]); 70 return 0; 71 }