• luoguP5105 不强制在线的动态快速排序


     emm

    可重集合没用用。直接变成不可重复集合

    有若干个区间

    每个区间形如[L,R]

    [L,R]计算的话,就是若干个连续奇数的和。拆位统计1的个数

    平衡树维护

    加入一个[L,R],把相交的区间合并。之后相邻不相交的部分O(1)计算贡献到答案里。

    O(nlogn+30n)

     不强制在线的动态快速排序

    写起来并不太好写

    set就可以

    删除一些区间,合并成大区间

    要分类讨论

    至于calc(l,r)

    有O(1)公式,可以不用按位:

    第一个第二个发现了,后面就是多余位置处理即可。

    代码:

    1.注意插入区间被包含的情况,删掉前驱,R还要取一个max

    2.按位的话,最高的是1e9+1e9=2e9,是1<<30,不是29.。。

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    int q;
    struct po{
        ll l,r;
        po(){}
        po(int x,int y){
            l=x;r=y;
        }
        bool friend operator <(po a,po b){
            if(a.l!=b.l) return a.l<b.l;
            return a.r<b.r;
        }
    };
    set<po>s;
    set<po>::iterator it,le,ri;
    ll ans;
    ll pre(int x,ll p){
        if(p==0) return x%2;
        if(p==1) {
            if(x%4==0) return 0;
            if(x%2==0) return 1;
            if(x%4==1) return 0;
            if(x%4==3) return 1;
        }
        x=x%(1<<p);
        if(x==0) return (1<<(p-1))%2;
        return max(0,x-(1<<(p-1)))%2;
    }
    ll clac(int l,int r){
        ll ret=0;
        l=(l+l+1)/2+1;
        r=(r+r-1)/2+1;
        if(l>r) return 0;
        for(ll i=30;i>=0;--i){
            ret+=(pre(r,i)-pre(l-1,i)+2+2+2)%2*(1<<i);
        }
        return ret;
    }
    void dele(int typ){
    
        if(typ==0){//pre and bac and me    
            ll tmp=clac((*it).l,(*it).r);
            ans^=tmp;
            ri=it;
            ++ri;
            if(ri!=s.end()){
                ans^=((*ri).l)*((*ri).l)-((*it).r)*((*it).r);
            }
            le=it;
            if(le!=s.begin()){
                --le;
                ans^=((*it).l)*((*it).l)-((*le).r)*((*le).r);
            }
            s.erase(it);
        }
        else if(typ==1){//bac and me
            ll tmp=clac((*it).l,(*it).r);
            ans^=tmp;
            ri=it;
            ++ri;
            if(ri!=s.end()){
                ans^=((*ri).l)*((*ri).l)-((*it).r)*((*it).r);
            }
            s.erase(it);
        }else {//only bac
            ri=it;
            ++ri;
            if(ri!=s.end()){
                ans^=((*ri).l)*((*ri).l)-((*it).r)*((*it).r);
            }
        }
    }
    void ins(int l,int r){
        if(s.empty()){
            ans^=clac(l,r);
            s.insert(po(l,r));
        }else{
            it=s.lower_bound(po(l,r));
            ll L=l,R=r;
            //bool fl=false;
            if(it!=s.begin()){
                --it;
                if((*it).r>=l-1){
                    L=min(L,(*it).l);
                    R=max(R,(*it).r);
                    dele(0);
                    //fl=true;
                    it=s.lower_bound(po(l,r));
                }else{
                    dele(2);
                }
            }
            while(1){
                it=s.lower_bound(po(l,r));
                if(it==s.end()) break;
                if((*it).l>r) break;
                R=max(R,(*it).r);
                dele(1);
            }
            
            if(it!=s.end()){
                ans^=((*it).l)*((*it).l)-R*R;
            }
            if(it!=s.begin()){
                --it;
                ans^=L*L-((*it).r)*((*it).r);
            }
            ans^=clac(L,R);
            s.insert(po(L,R));
        }
    }
    int main(){
        rd(q);
        int op,l,r;
        while(q--){
            rd(op);
            if(op==1){
                rd(l);rd(r);
                ins(l,r);
            }else{
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    
    }
    signed main(){
    //    freopen("data.in","r",stdin);
    //    freopen("my.out","w",stdout);
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/1/16 9:17:43
    */
  • 相关阅读:
    VSCode添加git bash作为默认终端
    Git无法提交branch is currently checked out
    Excel创建下拉列表限制数据有效性
    Windows添加管理员用户
    从Windows10中彻底删除【3D对象】文件夹
    异常处理机制
    泛型
    Java集合
    String、StringBuffer、StringBulider
    System类与Runtime类
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10267818.html
Copyright © 2020-2023  润新知