zoukankan      html  css  js  c++  java
  • Codeforces Round #365 (Div. 2) D

    http://codeforces.com/contest/703/problem/D

    题意:

    给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和。

    思路:

    这儿利用一下异或和的性质,在一个区间中,我们如果把所有数字都异或的话,可以发现最后偶数次的数字异或后都变成了0,只剩下了奇数次的数字异或。

    举个例子,{1,2,3,2,3,5}

    异或和是1^2^3^2^3^5=1^5

    因为最后要计算偶数次数字的异或和,那么最后我们只需要再异或上该区间内所有不同数字即可。

    那么我们可以先计算出前缀异或和,之后就只要求区间上的不同数字的异或和即可。

    离线树状数组和在线树状数组的不同点是前者是先把所有询问存储下来,排序后再处理。

    拿这道题目来说,我们将询问按照右端点从小到大排序,然后依次计算询问,如果当前数字在之前已经出现过,那么就先删去它,然后再插入该数字,这样就保证了这个区间内不同的数字只出现一次,具体可见代码。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<string>
     6 #include<vector>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 using namespace std;
    11 typedef long long LL;
    12 
    13 const int maxn=1e6+5;
    14 
    15 struct node
    16 {
    17     int l,r;
    18     int id;
    19 }q[maxn];
    20 
    21 map<int,int> pos;
    22 
    23 int n,m;
    24 int a[maxn];
    25 int c[maxn];
    26 int sum[maxn];
    27 int pre[maxn];
    28 LL ans[maxn];
    29 
    30 bool cmp(node a,node b)
    31 {
    32     return a.r<b.r||(a.r==b.r && a.l<b.l);
    33 }
    34 
    35 int lowbit(int x)
    36 {
    37     return x&-x;
    38 }
    39 
    40 int XOR_sum(int x)
    41 {
    42     int ret=0;
    43     while(x>0)
    44     {
    45         ret^=c[x];
    46         x-=lowbit(x);
    47     }
    48     return ret;
    49 }
    50 
    51 void add(int x,int d)
    52 {
    53     while(x<=maxn)
    54     {
    55         c[x]^=d;
    56         x+=lowbit(x);
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     //freopen("D:\input.txt","r",stdin);
    63     while(~scanf("%d",&n))
    64     {
    65         pos.clear();
    66         sum[0]=0;
    67         for(int i=1;i<=n;i++)
    68         {
    69             scanf("%d",&a[i]);
    70             sum[i]=sum[i-1]^a[i];
    71             pre[i]=pos[a[i]];   //记录a[i]这个数前面出现的位置
    72             pos[a[i]]=i;   //更新a[i]最晚的出现位置
    73         }
    74         scanf("%d",&m);
    75         for(int i=0;i<m;i++)
    76         {
    77             scanf("%d%d",&q[i].l,&q[i].r);
    78             q[i].id=i;
    79         }
    80         sort(q,q+m,cmp);
    81         memset(c,0,sizeof(c));
    82         for(int i=0,r=1;i<m;i++)
    83         {
    84             while(r<=q[i].r)
    85             {
    86                 if(pre[r])    //如果第r个位置的数之前已经出现过,就删去这个数
    87                     add(pre[r],a[r]);
    88                 add(r,a[r]);   //添加第r个数
    89                 r++;
    90             }
    91             ans[q[i].id]=XOR_sum(q[i].r)^XOR_sum(q[i].l-1)^sum[q[i].r]^sum[q[i].l-1];
    92         }
    93         for(int i=0;i<m;i++)
    94             printf("%I64d
    ",ans[i]);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    关于并发量的简单计算公式
    kbmmw中向服务器端传递对象的一种简单方式
    tms web core 里面调用pascal 过程。
    tms web core 通过URL 传递参数
    tms web core 与 kbmmw 第一次亲密接触
    kbmmw 的HTTPSmartService 上传文件到服务器端
    kbmmw 中的进程管理小工具
    kbmmw 5.06.20 发布
    kbmmw ORM 对象定义语法简析
    kbmmw 5.06.00 beta 发布
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6868659.html
Copyright © 2011-2022 走看看