zoukankan      html  css  js  c++  java
  • Codeforces 617E: XOR and Favorite Number(莫队算法)

    题目链接

    题意大致是说,给出一个长为n(n<=1e5)的数组,给定一个k(k<=1e6),给出m(m<=1e5)个询问,每组询问中回答 从a_l到a_r有多少个连续的子序列满足异或和等于k

    这里采用莫队的方法

    使用普通莫队的前提:对于序列上的区间询问问题,如果从 [l, r][l,r] 的答案能够 O(1) 扩展到 [l - 1, r], [l + 1, r],[l, r + 1],[l, r - 1][l1,r],[l+1,r],[l,r+1],[l,r1] 的答案,那么可以在 O(nn​​) 的复杂度内求出所有询问的答案。

    降低复杂度的环节:离线处理询问,对每个询问按照 l/sz为第一关键字,r为第二关键字 由小到大排序,这样使复杂度降为了
    O(nn​​) ,证明略。

    下面附上来自jlx的代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int maxn=1e5+7;
    const int maxv=1<<20;
    int pre[maxn],pos[maxn];
    int cnt[maxv],k;
    LL ans[maxn];
    int L=1,R=0;
    LL Ans;
    
    struct Query
    {
        int l,r,id;
        bool operator<(const Query& b) const    //pos[l]为第一关键字,r为第二 
        {
            if(pos[l]==pos[b.l]) return r<b.r;
            return pos[l]<pos[b.l];
        }                                        //按照如此排出来的顺序,可以降低复杂度 
    }Q[maxn];
    
    void add(int x)
    {
        Ans+=cnt[pre[x]^k];
        ++cnt[pre[x]];
    }
    void del(int x)
    {
        --cnt[pre[x]];
        Ans-=cnt[pre[x]^k];
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m>>k;
        int sz=sqrt(n);    //sz:块的大小 
        for(int i=1;i<=n;i++)
        {
            cin>>pre[i];
            pre[i]^=pre[i-1];
            pos[i]=i/sz;
        }
        for(int i=1;i<=m;i++)
        {
            cin>>Q[i].l>>Q[i].r;
            Q[i].id=i;
        }
        sort(Q+1,Q+1+m);
        Ans=0;
        cnt[0]=1;
        for(int i=1;i<=m;i++)
        {
            while(L>Q[i].l)
            {
                --L;
                add(L-1);
            }
            while(L<Q[i].l)
            {
                del(L-1);
                ++L;
            }
            while(R>Q[i].r)
            {
                del(R);
                --R;
            }
            while(R<Q[i].r)
            {
                ++R;
                add(R);
            }
            ans[Q[i].id]=Ans;
        }
        for(int i=1;i<=m;i++)
            cout<<ans[i]<<endl;
    }
  • 相关阅读:
    vue-cli3配置开发环境和生产环境
    vue配置开发环境和生产环境
    js实现div拖拽互换位置效果
    axios用post提交的数据格式
    面试题会被问及哪些?(总结)
    深入理解vue
    nodejs 前端项目编译时内存溢出问题的原因及解决方案
    MUI框架开发HTML5手机APP(一)--搭建第一个手机APP
    关于if省略{}时的一些问题
    函数声明的两种形式的区别
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/7200191.html
Copyright © 2011-2022 走看看