zoukankan      html  css  js  c++  java
  • Codeforces617 E . XOR and Favorite Number(莫队算法)

    本题是经典的莫队算法

    莫队算法是离线查询的一种复杂度优秀的暴力算法。

    首先我们需要注意异或的几个性质,相同数字异或等于0,所以我们考虑前缀和,因为从ai-aj的异或值就等于pre[i-1]^pre[j] 前缀和的异或,因为相同部分会抵消。

    莫队一般和分块相结合,我们需要维护一个cnt数组,cnt[a[x]]表示异或结果是a[x]的值有多少,这就可以表示贡献度。

    几个坑点:

    1.异或值可以大于原值,所以首先要注意int,其次数组范围要开大一点

    2.为什么在维护add的时候要先算贡献再加,而sub时要先减?

    因为有一种特殊情况会使x^k=x,也就是k=0的时候,那么这个时候不能算这个区间,因为这是自身的匹配是空匹配,因为前缀和是pre[i-1]^pre[j],这种情况就是pre[i-1]^pre[i-1]这里面是没有值的。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=1<<20;
    ll ans[N];
    ll cnt[N];
    ll pos[N];
    ll a[N];
    ll res;
    int n,m,k;
    struct node{
        int l,r;
        int k;
    }q[N];
    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 add(int x){
        res+=cnt[a[x]^k]; //贡献 
        cnt[a[x]]++;
    }
    void sub(int x){
        cnt[a[x]]--;
        res-=cnt[a[x]^k];
    }
    int main(){
        int i;
        cin>>n>>m>>k;
        int block=sqrt(n);
        for(i=1;i<=n;i++){
            cin>>a[i];
            a[i]^=a[i-1];
            pos[i]=(i-1)/block+1;
        }
        for(i=1;i<=m;i++){
            cin>>q[i].l>>q[i].r;
            q[i].k=i;
        }
        sort(q+1,q+1+m,cmp);
        int l=1;
        int r=0;
        cnt[0]=1;
        for(i=1;i<=m;i++){
            while(q[i].l<l){
                l--;
                add(l-1);
            }
            while(q[i].r>r){
                r++;
                add(r);
            }
            while(q[i].l>l){
                sub(l-1);
                l++;
            }
            
            while(q[i].r<r){
                sub(r);
                r--;
            }
            ans[q[i].k]=res;
        }
        for(i=1;i<=m;i++)
        cout<<ans[i]<<endl; 
        
    }
    View Code
  • 相关阅读:
    【算法总结】搜索算法(上)
    New Beginning
    好想退役啊【笑
    【NOIP2012】DAY1+DAY2题解
    【NOIP2013】Day2不完全题解+代码
    【NOIP2013】DAY1题解+代码
    【NOIP2014】DAY2题解+代码
    【游记】NOIP2015造纸记
    【ACM-ICPC 2018 徐州赛区网络预赛】E. End Fantasy VIX 血辣 (矩阵运算的推广)
    【ACM-ICPC 2018 沈阳赛区网络预赛】不太敢自称官方的出题人题解
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12241039.html
Copyright © 2011-2022 走看看