悬赏一个关注,整体二分求调
查看原帖
悬赏一个关注,整体二分求调
511271
ダ月Nahida楼主2022/12/16 21:32

rt。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
struct tree{
	struct node{ll x,l;}tr[N<<3];
	void pushup(int rt){tr[rt].x=tr[rt<<1].x+tr[rt<<1|1].x;}
	void pushdown(int rt,int l,int r,int mid){
		if(!tr[rt].l) return;
		tr[rt<<1].x+=1ll*tr[rt].l*(mid-l+1);
		tr[rt<<1].l+=1ll*tr[rt].l;
		tr[rt<<1|1].x+=1ll*tr[rt].l*(r-mid);
		tr[rt<<1|1].l+=1ll*tr[rt].l;
		tr[rt].l=0;
	}void build(int rt,int l,int r,int a[]){
		if(l==r){tr[rt].x=a[l];return;}
		int mid=l+r>>1;build(rt<<1,l,mid,a);build(rt<<1|1,mid+1,r,a);
		pushup(rt);
	}void change(int rt,int l,int r,int x,int y,ll z){
		if(x<=l&&r<=y){tr[rt].x+=1ll*(r-l+1)*z;tr[rt].l+=1ll*z;return;}
		int mid=l+r>>1;pushdown(rt,l,r,mid);
		if(x<=mid) change(rt<<1,l,mid,x,y,z);if(y>mid) change(rt<<1|1,mid+1,r,x,y,z);
		pushup(rt);
	}ll query(int rt,int l,int r,int x,int y){
		if(x<=l&&r<=y) return tr[rt].x;
		int mid=l+r>>1;pushdown(rt,l,r,mid);ll ans=0;
		if(x<=mid) ans+=query(rt<<1,l,mid,x,y);if(y>mid) ans+=query(rt<<1|1,mid+1,r,x,y);
		return ans;
	}
}Tr;
struct node{int h,k,id;}Q[N],Q1[N],Q2[N];
int H[N<<1],Ne[N<<1],tp=0,n,m,T,l[N],r[N],val[N],ans[N];
void add(int x,int y){H[++tp]=y;Ne[tp]=Q[x].h;Q[x].h=tp;}
void solve(int lt,int rt,int x,int y){
	if(lt==rt){
		for(int i=x;i<=y;i++)
			ans[Q[i].id]=lt;
		return;
	}int mid=lt+rt>>1;int tp1=0,tp2=0;
	for(int i=lt;i<=mid;i++) Tr.change(1,1,m<<1,l[i],r[i],val[i]);
	for(int i=x;i<=y;i++){
		ll tem=0;for(int j=Q[i].h;j&&tem<=Q[i].k;j=Ne[j]) tem+=Tr.query(1,1,m<<1,H[j],H[j]+m);
		if(tem>=Q[i].k) Q1[++tp1]=Q[i];
		else Q[i].k-=tem,Q2[++tp2]=Q[i];
	}for(int i=lt;i<=mid;i++) Tr.change(1,1,m<<1,l[i],r[i],-val[i]);
	for(int i=1;i<=tp1;i++) Q[i+x-1]=Q1[i];
	for(int i=1;i<=tp2;i++) Q[i+tp1+x-1]=Q2[i];
	solve(lt,mid,x,x+tp1-1);solve(mid+1,rt,x+tp1,y);
}
int main(){
	scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x;scanf("%d",&x);add(x,i);}
	for(int i=1;i<=n;i++){scanf("%d",&Q[i].k);Q[i].id=i;}scanf("%d",&T);
	for(int i=1;i<=T;i++) scanf("%d%d%d",&l[i],&r[i],&val[i]);
	for(int i=1;i<=T;i++) if(l[i]>r[i]) r[i]+=m;solve(1,T+1,1,n);
	for(int i=1;i<=n;i++){
		if(ans[i]==T+1) puts("NIE");
		else printf("%lld\n",ans[i]);
	}
	return 0;
}
2022/12/16 21:32
加载中...