近似成等差数列递增。a≤b≤n,1 操作中|c|≤n,2 操作中|c|≤maxlongint
线段树套线段树,外部线段树记录第k大(数据没有负数),内部线段树是维护标记的区间线段树,表示这里面几个数..
插入c的时候转换为第k大(c=n-c+1),然后用类似二分的方法找c,输出的时候换为n-solve()+1
#include
#include
#include
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define q 200005
#define w 20000005
using namespace std;
int root[q]={0},ct=0,n,m;
int a,b,c;
struct Segtree
{
int l,r,sum,lazy;
}tree[w];
void Pushdown(int x,int l,int r)
{
if(tree[x].lazy==0||l==r)return;
if(tree[x].l==0)tree[x].l=++ct;
if(tree[x].r==0)tree[x].r=++ct;
int mid=(l+r)>>1;
tree[tree[x].l].lazy+=tree[x].lazy;
tree[tree[x].r].lazy+=tree[x].lazy;
tree[tree[x].l].sum+=tree[x].lazy*(mid-l+1);
tree[tree[x].r].sum+=tree[x].lazy*(r-mid);
tree[x].lazy=0;
}
void Pushup(int x)
{
tree[x].sum=tree[tree[x].l].sum+tree[tree[x].r].sum;
}
void change(int &root,int l,int r,int a,int b)
{
if(root==0){root=++ct;}//
Pushdown(root,l,r);
if(l==a&&r==b)
{
tree[root].sum+=r-l+1;
tree[root].lazy++;
return;
}
int mid=(l+r)>>1;
// if(a<=mid)change(tree[root].l,l,mid,a,b);
// if(r>mid)change(tree[root].r,mid+1,r,a,b);
if(b<=mid)change(tree[root].l,l,mid,a,b);
else if(a>mid)change(tree[root].r,mid+1,r,a,b);
else
{
change(tree[root].l,l,mid,a,mid);
change(tree[root].r,mid+1,r,mid+1,b);
}
Pushup(root);
}
void MDF()
{
int o=1,l=1,r=n;
while(l!=r)
{
int mid=(l+r)>>1;
change(root[o],1,n,a,b);
if(c<=mid){o=L(o);r=mid;}
else {o=R(o);l=mid+1;}
}
change(root[o],1,n,a,b);
}
int get(int root,int l,int r,int a,int b)
{
if(root==0)return 0;
Pushdown(root,l,r);
if(l==a&&r==b)return tree[root].sum;
int mid=(l+r)>>1;
if(b<=mid)return get(tree[root].l,l,mid,a,b);
else if(a>mid)return get(tree[root].r,mid+1,r,a,b);
else
{
return get(tree[root].l,l,mid,a,mid)+get(tree[root].r,mid+1,r,mid+1,b);
}
}
int Get()
{
int o=1,l=1,r=n;
while(l!=r)
{
int mid=(l+r)>>1;
int t=get(root[L(o)],1,n,a,b);
// cout<<"**"<