• Codeforces703D-Mishka and Interesting sum-离线树状数组


    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

    题意:传送门

     原题目描述在最下面。
     询问一个区间内出现次数为偶数次的数字的异或和。

    思路:

     先求出区间异或前缀和,其实就是出现次数为奇数次的数字的异或前缀和和。
     然后用离线树状数组树状维护区间内区间内每种数字的前缀和。
     最后的答案就是上面两个前缀和 差分一下 的异或和。

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<assert.h>
    #include<bitset>
    #include<unordered_map>
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) (x)&(-(x))
    #define all(x) (x).begin(),(x).end()
    using namespace std;
    typedef long long LL;
    const int INF = 0x3f3f3f3f;
    const int N = (int)1e6 +107;
    int n, m;
    LL pre[N], bit[N], ar[N], ans[N];
    unordered_map<LL,int> vis;
    void add(int x,LL c){
      while(x<=n){
        bit[x] ^= c;
        x += lowbit(x);
      }
    }
    LL query(int x){
      LL sum = 0;
      while(x){
        sum ^= bit[x];
        x -= lowbit(x);
      }
      return sum;
    }
    struct lp{
      int l, r, id;
    }cw[N];
    bool cmp(lp &a, lp &b){
      if(a.r!=b.r)return a.r<b.r;
      return a.l<b.l;
    }
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("E://ADpan//in.in", "r", stdin);
        //freopen("E://ADpan//out.out", "w", stdout);  
    #endif
      while(~scanf("%d",&n)){
        memset(pre,0,sizeof(pre));
        memset(bit,0,sizeof(bit));
        for(int i=1;i<=n;++i){
          scanf("%lld",&ar[i]);
          pre[i] = pre[i-1]^ar[i];
        }
        scanf("%d",&m);
        for(int i=0;i<m;++i){
          scanf("%d%d", &cw[i].l, &cw[i].r);
          cw[i].id = i;
        }
        sort(cw,cw+m,cmp);
        vis.clear();
        int r = 0;
        for(int i=0;i<m;++i){
          while(r<cw[i].r){
            ++r;
            add(r, ar[r]);
            if(vis[ar[r]]==0) vis[ar[r]] = r;
            else {
              add(vis[ar[r]], ar[r]);
              vis[ar[r]] = r;
            }
          }
          ans[cw[i].id]=pre[cw[i].r]^pre[cw[i].l-1]^query(cw[i].r)^query(cw[i].l-1);
        }
        for(int i=0;i<m;++i){
          printf("%lld%c", ans[i], " 
    "[i==m-1]);
        }
      }
      return 0;
    }
    

    ####原题目描述: ![这里写图片描述](https://img-blog.csdn.net/20180726164614519?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5NTk5MDY3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
  • 相关阅读:
    14:求满足条件的3位数
    1696:逆波兰表达式
    筛法求素数 6分
    1751:分解因数
    1750:全排列
    1788:Pell数列
    666:放苹果
    06:寻宝
    04:最匹配的矩阵
    雷电
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/9513270.html
Copyright © 2020-2023  润新知