一道二分水题
读题,他要求满足条件的木棍最长的长度
发现,答案明显满足二分性(最终木根长度越小,可以分出的木棍数就越多)
所以,我们可以直接二分答案,假设当前二分出的答案为x
那么, 对于一个长度为y的木棍来说,它可以分出的最多的长度为x的木棍就是
所以,总共最多可以分出的,长度为x的木棍数就是:
我们将这个值和k比较一下,如果大于k,就说明可以分到x,就往右二分,否则就往左二分,即可
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3;
struct splay{
    int w,son[2],fa,laz,tot,cnt;
}t[N];
int al,root;
inline bool wy(int x){
    return t[t[x].fa].son[1]==x;
}
inline void update(int x){
    t[x].tot=(t[t[x].son[0]].tot+t[t[x].son[1]].tot+t[x].cnt);
}
inline void rotate(int x){
    int y=t[x].fa,z=t[y].fa,k=wy(x),w=t[x].son[k^1];
    t[y].son[k]=w,t[w].fa=y;
    t[x].fa=z,t[z].son[wy(y)]=x;
    t[x].son[k^1]=y,t[y].fa=x;
    update(y),update(x);
}
inline void splay(int x,int gol=0){
    while(t[x].fa!=gol){
        int y=t[x].fa,z=t[y].fa;
        if(z!=gol){
            if(wy(x)==wy(y)){
                rotate(y);
            }else{
                rotate(x);
            }
        }
        rotate(x);
    }
    if(!gol){
        root=x;
    }
}
inline void insert(int x){
    int now=root,fu=0;
    while(now){
        fu=now,now=t[now].son[x>t[now].w];
    }
    now=++al;
    if(fu){
        t[fu].son[x>t[now].w]=al;
    }
    t[now].w=x,t[now].fa=fu;
    t[now].tot=t[now].cnt=1;
    splay(now);
}
inline void down(int now){
    if(t[now].laz){
        swap(t[now].son[0],t[now].son[1]);
        t[t[now].son[0]].laz^=1;
        t[t[now].son[1]].laz^=1;
        t[now].laz=0;
    }
}
inline int kth(int k){
    int now=root;
    while(true){
        down(now);
        if(t[t[now].son[0]].tot>=k){
            now=t[now].son[0];
        }else if(t[t[now].son[0]].tot+t[now].cnt<k){
            k-=(t[t[now].son[0]].tot+t[now].cnt),now=t[now].son[1];
        }else{
            return now;
        }
    }
}
inline void reverse(int l,int r){
    int x=kth(l-1),y=kth(r+1);
    splay(x),splay(y,x);//这样splay后,y的左子树编号全为l-r
    t[t[y].son[0]].laz^=1;
}
int n,m;
inline void print(int now){
    down(now);
    if(t[now].son[0]){
        print(t[now].son[0]);
    }
    if(now>1&&now<n)
        printf("%d ",now-1);
    if(t[now].son[1]){
        print(t[now].son[1]);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    n+=2;
    for(int i=1;i<=n;++i){
        insert(i);
    }
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        ++l,++r;
        reverse(l,r);
    }
    print(root);
    return 0;
}