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

传送门

首先我们要知道怎么快速求\(1\)\(n\)的异或和,大概是这么个东西

if(x%4==0) return 0;
if(x%4==2) return 2;
if(x%4==1) return x+x-1;
return x+x+1;

(别问我为什么我网上找了篇证明结果代码都错的……)

不难发现集合虽然可重但是没有影响,因为只有不同的会有贡献,所以我们只要维护所有的区间,区间答案用上面公式\(O(1)\),区间之间的答案也可以\(O(1)\),所以只要用set维护好区间即可

虽然有那么一点麻烦就是了……

// luogu-judger-enable-o2
//minamoto
#include<bits/stdc++.h>
#define rr register
#define ll long long
#define IT set<node>::iterator
#define ITT deque<IT>::iterator
#define fp(i,a,b) for(rr int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(rr int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
    rr int res,f=1;rr char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(rr ll x){
    if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
struct node{
    int l,r;ll v;
    node(int l=0,int r=0,ll v=0):l(l),r(r),v(v){}
    inline bool operator <(const node &b)const{return l<b.l;}
};set<node>s;deque<IT>rub;int q,op,l,r;ll x,ans;
inline ll calc(int n){int t=n%4;return t==0?0:t==2?2:t==1?n+n-1:n+n+1;}
inline void L(IT it){
    if(it!=s.begin()){
        x=1ll*it->l*it->l,--it;
        ans^=x-(1ll*it->r*it->r);
    }
}
inline void R(IT it){
    if(it!=--s.end()){
        x=1ll*it->r*it->r,++it;
        ans^=(1ll*it->l*it->l)-x;
    }
}
void ins(int l,int r){
    IT it=s.lower_bound(node(l)),itl=it;
    while(true){
        if(itl==s.begin())break;--itl;
        if(itl->r>=l-1)rub.push_front(itl);else break;
    }itl=it;while(true){
        if(itl==s.end())break;
        if(itl->l<=r+1)rub.push_back(itl);else break;
        ++itl;
    }for(ITT itr=rub.begin();itr!=rub.end();++itr){
        IT it=*itr;if(it->l<l)l=it->l;if(it->r>r)r=it->r;
        L(it),ans^=it->v;
    }if(!rub.empty())R(*--rub.end());
    else {
        IT it=s.lower_bound(node(l));
        if(it!=s.end())L(it);
    }for(ITT itr=rub.begin();itr!=rub.end();++itr)s.erase(*itr);
    rub.clear(),it=s.insert(node(l,r,calc(r)^calc(l))).first;
    L(it),R(it),ans^=it->v;
}
int main(){
//	freopen("testdata.in","r",stdin);
    q=read();while(q--){
        if(op=read(),op==1)l=read(),r=read(),ins(l,r);
        else print(ans);
    }return Ot(),0;
}
posted @ 2018-12-17 12:57  bztMinamoto  阅读(185)  评论(0编辑  收藏  举报
Live2D