整体二分求调(悬1关
查看原帖
整体二分求调(悬1关
556975
PNNNN楼主2024/1/2 17:29
#include<bits/stdc++.h>
#define int long long
using namespace std;

int n,m,q,p[300005],ans[300005];

int lst[300005],lst1[300005],lst2[300005],siz1,siz2;

struct stone{
	int l,r,x;
}st[300005];

int t[300005];

vector <int> to[300005];

inline int lowbit(int x){return x&-x;}

inline void add(int x,int val){
	while(x<=m+m){
		t[x]+=val,x+=lowbit(x);
	}return;
}

inline int query(int x){
	int res=0;
	while(x>0){
		res+=t[x],x-=lowbit(x);
	}return res;
}

inline void solve(int l,int r,int head,int tail){
	if(l==r){
		for(int i=head;i<=tail;i++){
			ans[lst[i]]=l;
		}
	}else{
		int mid=l+r>>1; 
		for(int i=l;i<=mid;i++){
			add(st[i].l,st[i].x),add(st[i].r+1,-st[i].x);
		}siz1=siz2=0;
		for(int i=head;i<=tail;i++){
			int res=0;
			for(int j:to[lst[i]]){
				res+=query(j)+query(j+m);
			}
			if(res>=p[lst[i]])lst1[++siz1]=lst[i];
			else lst2[++siz2]=lst[i],p[lst[i]]-=res;
		}
		for(int i=head;i<=head+siz1-1;i++){
			lst[i]=lst1[i-head+1];
		}
		for(int i=head+siz1;i<=head+siz1+siz2-1;i++){
			lst[i]=lst2[i-head-siz1+1];
		}
		for(int i=l;i<=mid;i++){
			add(st[i].l,-st[i].x),add(st[i].r+1,st[i].x);
		}
		solve(l,mid,head,head+siz1-1);
		solve(mid+1,r,head+siz1,tail);
	}return;
}

inline int read(){
	register int x=0,t=0;
	static char ch=getchar();
	while(!isdigit(ch)) t|=(ch=='-'),ch=getchar();
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return t?-x:x;
}

signed main(){
	n=read(),m=read();
	for(int i=1;i<=m;i++){
		int x=read();
		to[x].push_back(i);
	}
	for(int i=1;i<=n;i++){
		p[i]=read(),lst[i]=i;
	}q=read();
	for(int i=1;i<=q;i++){
		int l=read(),r=read(),x=read();
		if(l>r)r+=m;st[i]={l,r,x};
	}solve(1,q+1,1,n);
	for(int i=1;i<=n;i++){
		if(ans[i]==q+1){
			cout<<"NIE\n";
		}else{
			cout<<ans[i]<<'\n';
		}
	}
	return 0;
}

提交记录

2024/1/2 17:29
加载中...