导航

离线维护 支持插入数 的序列

论离线维护插入单点

碰到过好多类似的题,都在维护这个序列中卡住了,这是个简单易懂\(O(n log^2_2n)\)

我们考虑从后往前维护序列

对于第n个插入的数,它最后所在的位置p就是预期位置

然后原本在p后面的数就会集体往后移一位,我们用树状数组维护要往后移几位

例题

#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
const int N=4e5+5;
int n,cnt,m,t[N<<2];
vector<int>vec[N];
vector<pii>que[N];
int ans[N],c[N];
void add(int x,int y){for(;x<=m;x+=x&-x)c[x]+=y;}
int ask(int x){int res=0;for(;x;x&=x-1)res+=c[x];return res;}
void change(int k,int l,int r,int x){
    if(l==r){t[k]++;return;}
    int mid=l+r>>1;
    if(x<=mid)change(k*2,l,mid,x);
    else change(k*2+1,mid+1,r,x);
    t[k]=t[k*2]+t[k*2+1];
}
int ask(int x,int l,int r,int L,int R){
	if(L>R)return 0;
	if(l>=L&&r<=R)return t[x];
	int mid=(l+r)>>1,rec=0;
	if(mid>=L)rec=ask(x<<1,l,mid,L,R);
	if(mid+1<=R)rec+=ask(x<<1|1,mid+1,r,L,R);
	return rec;
}
int main(){
    freopen("queue.in","r",stdin);
    freopen("queue.out","w",stdout);
    scanf("%d",&n);
    for(int i=1,c,v;i<=n;i++){
    	scanf("%d%d",&c,&v);
    	int pos,id;
    	if(vec[c].empty()||ask(1,1,n,vec[c].back()+1,cnt)>v)change(1,1,n,++cnt),vec[c].push_back(cnt),pos=cnt,id=0;
    	else{
    		int l=0,r=vec[c].size()-1;
    		while(l<r){
    			int mid=(l+r)>>1;
    			if(ask(1,1,n,vec[c][mid]+1,cnt)<=v)r=mid;
    			else l=mid+1;
            }
            pos=vec[c][l];
            id=ask(1,1,n,vec[c][l],vec[c][l])-min(ask(1,1,n,vec[c][l],vec[c][l]),v-ask(1,1,n,vec[c][l]+1,cnt));
            change(1,1,n,vec[c][l]);
        }
        que[pos].push_back(make_pair(id,i));
    }
    for(int i=1;i<=cnt;i++){
        m=que[i].size();
        for(int j=1;j<=m;j++)c[j]=0,ans[j]=0;
        for(int j=1;j<=m;j++)add(j,1);
        for(int j=m-1;j>=0;j--){
            int x=que[i][j].first;
            int l=1,r=m;
            while(l<r){
                int mid=l+r+1>>1;
                if(ask(mid-1)<=x)l=mid;
                else r=mid-1;
            }
            ans[l]=que[i][j].second;
            add(l,-1);
        }
        for(int j=1;j<=m;j++)printf("%d ",ans[j]);
    }
    puts("");
    return 0;
}

posted on 2022-09-24 14:25  CHK666  阅读(29)  评论(0编辑  收藏  举报