zoukankan      html  css  js  c++  java
  • 2020牛客多校(五) H

    这道题我们发现固定一个端点,那么和他不同的或值答案就是不超过log个,因为就算每个只少一个0,那也只有20位

    现在的问题是如何去重,采用的方法是对于每个右端点,用mp查找与他或起来的不同值,绑定一个三元组表示或值为u的键值对为i,j,这里我们可以覆盖掉一些被包含的点,因为不可能成为答案

    之后继续去重,把包含的区间去除掉,采用的方法是排序。

    之后就是个二维数点的模板,可以采用主席树来维护,这里抄了一下别人的板子

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define lson tr[rt].l
    #define rson tr[rt].r
    #define mid ((l+r)>>1)
    #define x first
    #define y second
    typedef pair<int,int> pll;
    typedef long long ll;
    const int N=1e6+100;
    const int mod=1e9+7;
    struct node{int l,r,sum;}tr[N<<5];
    int tot;
    void build(int &rt,int l,int r){
        rt=++tot;
        if(l==r) 
            return;
        build(lson,l,mid);
        build(rson,mid+1,r);
    }
    void add(int &rt,int l,int r,int pre,int pos,int val){
        rt=++tot;tr[rt]=tr[pre];tr[rt].sum+=val;
        if(l==r) return;
        if(pos<=mid) add(lson,l,mid,tr[pre].l,pos,val);
        else add(rson,mid+1,r,tr[pre].r,pos,val);
    }
    int query(int rt,int l,int r,int pre,int ql,int qr){
        if(ql<=l&&r<=qr) return tr[rt].sum-tr[pre].sum;
        int ans=0;
        if(ql<=mid) ans+=query(lson,l,mid,tr[pre].l,ql,qr);
        if(mid<qr) ans+=query(rson,mid+1,r,tr[pre].r,ql,qr);
        return ans;
    }
    int a[N],root[N];
    map<int,int> tmp,mp;
    map<int,vector<pll>> po;
    vector<int> add1[N],sub[N];
    bool cmp(pll a,pll b){
        if(a.first==b.first){
            return a.second>b.second;
        }
        return a.first<b.first;
    }
    int main(){
        int n,m;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
            tmp.clear();
            for(auto u:mp) tmp[a[i]&u.first]=u.second;
            tmp[a[i]]=i;
            mp=tmp;
            for(auto u:mp)
                po[u.first].push_back({u.second,i});
        }
        for(auto u:po){
            auto v=u.second;
            sort(v.begin(),v.end(),cmp);
            vector<pll> sta;
            int i;
            for(i=0;i<v.size();i++){
                if(i==0)
                    sta.push_back(v[i]);
                if(v[i].second<=sta.back().second){
                    sta.pop_back();
                }
                sta.push_back(v[i]);
            }
            int sz=sta.size();
            for(i=0;i<sz;i++){
                add1[sta[i].first].push_back(sta[i].second);
                if(i)
                sub[sta[i-1].first].push_back(sta[i].second);
            }
        }
        build(root[0],1,n);
        for(i=1;i<=n;i++){
            int pre=root[i-1];
            for(auto u:add1[i]) add(root[i],1,n,pre,u,1),pre=root[i];
            for(auto u:sub[i]) add(root[i],1,n,pre,u,-1),pre=root[i];
        }
        int q,las=0;scanf("%d",&q);
        while(q--){
            int l,r;scanf("%d%d",&l,&r);
            l=(l^las)%n+1;r=(r^las)%n+1;
            if(l>r) swap(l,r);
            printf("%d
    ",las=query(root[n],1,n,root[l-1],1,r));
        }
    }
    View Code
  • 相关阅读:
    mysql总结
    git总结
    转:如何判断一家公司的好坏
    路越走越窄,尤其做技术的
    百度面试总结
    背叛
    which和whereis 命令
    bzoj3263 陌上花开 CDQ模板
    bzoj 2653middle
    暑假第十九测
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13430658.html
Copyright © 2011-2022 走看看