块状链表求调
查看原帖
块状链表求调
511389
xibaohe_KarlPeter楼主2023/11/15 11:22

CF上test3第5317个答案大了,求调

#include <bits/stdc++.h>

using namespace std;

const int N=2e5+10,K=451;
struct list
{
	int len,start,flag_sum;
	long long sum;	
}lis[K];
struct tab
{
	int nxt;
	long long val;
	bool flag;
};
vector <tab> a[K];
struct order{
	int tp,x,id;
}Q[N],b[N];
int plac[N],bel[N];
unordered_map <int,int> vis;
int n,tot,base,maxn,last;
long long all;

bool cmp(order x,order y)
{
	return x.x<y.x;
}

void init()
{
	for(int i=1;i<=n;i++)
		if(Q[i].x>0) b[++tot]=Q[i];
	sort(b+1,b+tot+1,cmp);
	for(int i=1;i<=tot;i++) plac[i]=b[i].x,vis[b[i].x]=i,b[i].x=i;
	for(int i=1;i<=n;i++){
		if(Q[i].x>0) Q[i].x=vis[Q[i].x];
		else Q[i].x=-vis[-Q[i].x];
	}
	base=sqrt(tot);
	for(int i=1;i<=tot;i++) bel[i]=(i-1)/base+1,maxn=max(maxn,bel[i]);
	for(int i=1;i<=maxn;i++) a[i].push_back((tab){0,0,0});
}

void delet(int tp,int x)
{
	if(tp) last--;
	x=-x;
	int p=bel[x],k=lis[p].start;
	lis[p].flag_sum-=tp,lis[p].len--;
	lis[p].sum-=plac[x],all-=plac[x];
	if(a[p][lis[p].start].val==plac[x]) lis[p].start=a[p][lis[p].start].nxt;
	else{
		while(a[p][a[p][k].nxt].val!=plac[x])
			k=a[p][k].nxt;
		a[p][k].nxt=a[p][a[p][k].nxt].nxt;
	}
}

void add(int tp,int x)
{
	if(tp) last++;
	int p=bel[x],k=++lis[p].len;
	lis[p].flag_sum+=tp;
	a[p].push_back((tab){0,0,0});
	a[p][k].val=plac[x],a[p][k].flag=tp;
	lis[p].sum+=plac[x],all+=plac[x];
	int tmp=lis[p].start;
	if(plac[x]>a[p][tmp].val){ //好像是对的 
		a[p][k].nxt=lis[p].start;
		lis[p].start=k;
	}else{
		while(a[p][tmp].nxt && a[p][a[p][tmp].nxt].val>plac[x])
			tmp=a[p][tmp].nxt;
		int tmp_late=a[p][tmp].nxt;
		a[p][tmp].nxt=k;a[p][k].nxt=tmp_late;
	}
}

long long query()
{
	int tmp_last=last,k=maxn,posi,flag_p=0;
	long long ans=0;
	if(tmp_last){
		while(tmp_last>lis[k].len)
			tmp_last-=lis[k].len,ans+=lis[k].sum,flag_p+=lis[k].flag_sum,k--;
		posi=lis[k].start;
		while(tmp_last>1){
			ans+=a[k][posi].val;
			posi=a[k][posi].nxt;
			flag_p+=a[k][posi].flag;
			tmp_last--;
		}
		if(flag_p+a[k][posi].flag<last){
			ans+=a[k][posi].val;
			posi=a[k][posi].nxt;
			flag_p+=a[k][posi].flag;
			tmp_last--;
		}else{
			while(a[k][posi].flag && posi)
				posi=a[k][posi].nxt;
			if(posi) ans+=a[k][posi].val;
			else{
				while(k && lis[k].flag_sum==lis[k].len)
					k--;
				if(k){
					posi=lis[k].start;
					while(posi && a[k][posi].flag) posi=a[k][posi].nxt;
					ans+=a[k][posi].val;
				} 
			}
		}
	}
	ans=ans+all;
	return ans;
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>Q[i].tp>>Q[i].x;
		Q[i].id=i; 
	}
	init();
	for(int i=1;i<=n;i++){
		int tp=Q[i].tp,x=Q[i].x;
		if(x<0) delet(tp,x);
		else add(tp,x);
		cout<<query()<<endl;
	}
	return 0;
}
2023/11/15 11:22
加载中...