제출 #1332463

#제출 시각아이디문제언어결과실행 시간메모리
1332463boclobanchat사탕 분배 (IOI21_candies)C++20
0 / 100
461 ms61480 KiB
#include"candies.h"
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+5;
const long long INF=1e18;
struct query
{
	int idx;
	bool ck;
	long long val;
};
struct node
{
	bool ck;
	pair<long long,int> mn,mx;
};
long long lazy[MAXN*4],fen[MAXN],cv[MAXN],sum=0;
node seg[MAXN*4];
vector<query> vq[MAXN];
node operator+(const node& a,const node& b)
{
	node c;
	c.ck=false,c.mn=c.mx={0,0};
	if(a.ck)
	{
		if(!c.ck) c.ck=true,c.mn=a.mn,c.mx=a.mx;
		else c.mn=min(c.mn,a.mn),c.mx=max(c.mx,a.mx);
	}
	if(b.ck)
	{
		if(!c.ck) c.ck=true,c.mn=b.mn,c.mx=b.mx;
		else c.mn=min(c.mn,b.mn),c.mx=max(c.mx,b.mx);
	}
	return c;
}
void updf(int i,int n,int val) { for(;i<=n;i+=i&-i) fen[i]+=val; }
long long getf(int i) { long long ans=0;for(;i;i-=i&-i) ans+=fen[i];return ans; }
void build(int l,int r,int pos)
{
	seg[pos]={false,{0,0},{0,0}};
	if(l==r) return ;
	int mid=(l+r)/2;
	build(l,mid,pos*2);
	build(mid+1,r,pos*2+1);
}
void down(int pos)
{
	long long val=lazy[pos];
	if(seg[pos*2].ck) seg[pos*2].mn.first+=val,seg[pos*2].mx.first+=val;
	if(seg[pos*2+1].ck) seg[pos*2+1].mn.first+=val,seg[pos*2+1].mx.first+=val;
	lazy[pos*2]+=val,lazy[pos*2+1]+=val;
	lazy[pos]=0;
}
void updset(int l,int r,int i,bool ck,int pos)
{
	if(i<l||r<i) return ;
	if(l==r)
	{
		if(!ck) seg[pos]={false,{0,0},{0,0}};
		else
		{
			long long res=-getf(i);
			seg[pos]={true,{res,i},{res,i}};
		}
		return ;
	}
	int mid=(l+r)/2;
	down(pos);
	updset(l,mid,i,ck,pos*2);
	updset(mid+1,r,i,ck,pos*2+1);
	seg[pos]=seg[pos*2]+seg[pos*2+1];
}
void update(int l,int r,int u,int v,long long val,int pos)
{
	if(v<l||r<u) return ;
	if(u<=l&&r<=v)
	{
		if(seg[pos].ck) seg[pos].mn.first+=val,seg[pos].mx.first+=val;
		lazy[pos]+=val;
		return ;
	}
	int mid=(l+r)/2;
	down(pos);
	update(l,mid,u,v,val,pos*2);
	update(mid+1,r,u,v,val,pos*2+1);
	seg[pos]=seg[pos*2]+seg[pos*2+1];
}
node get(int l,int r,int u,int v,int pos)
{
	if(u<=l&&r<=v) return seg[pos];
	int mid=(l+r)/2;
	down(pos);
	if(v<=mid) return get(l,mid,u,v,pos*2);
	if(mid+1<=u) return get(mid+1,r,u,v,pos*2+1);
	return get(l,mid,u,v,pos*2)+get(mid+1,r,u,v,pos*2+1);
}
int walk(int l,int r,node val,long long c,int pos)
{
	if(l==r) return l;
	int mid=(l+r)/2;
	down(pos);
	node res=val+seg[pos*2+1];
	if(!res.ck||res.mx.first-res.mn.first<=c) return walk(l,mid,res,c,pos*2);
	return walk(mid+1,r,val,c,pos*2+1);
}
int walk(int n,long long c)
{
	if(seg[1].mx.first-seg[1].mn.first<=c) return 0;
	return walk(1,n,{false,{0,0},{0,0}},c,1);
}
void updidx(int i,int n,query val)
{
	if(!val.ck)
	{
		sum-=cv[i];
		updf(i,n,-cv[i]);
		updset(1,n,i,false,1);
		update(1,n,i+1,n,cv[i],1);
	}
	else
	{
		sum+=(cv[i]=val.val);
		updf(i,n,cv[i]);
		updset(1,n,i,true,1);
		update(1,n,i+1,n,-cv[i],1);
	}
}
vector<int> distribute_candies(vector<int> c,vector<int> l,vector<int> r,vector<int> v)
{
	int n=c.size(),q=l.size();
	vector<int> ans;
	for(int i=0;i<q;i++)
	{
		vq[l[i]].push_back({i+1,true,v[i]});
		vq[r[i]+1].push_back({i+1,false,0});
	}
	build(0,q,1);
	for(int i=0;i<n;i++)
	{
		for(auto v:vq[i]) updidx(v.idx,q,v);
		int pos=walk(q,c[i]);
		node res=get(1,q,pos,q,1);
		if(!pos) res=res+(node){true,{0,0},{0,0}};
		if(!res.ck) ans.push_back(0);
		else if(res.mx.first-res.mn.first<=c[i]&&res.mn.first>=0) ans.push_back(sum);
		else
		{
			if(res.mn.second<res.mx.second) ans.push_back(min(1LL*c[i],-getf(res.mx.second)+sum));
			else ans.push_back(max(0LL,c[i]-getf(res.mn.second)+sum));
		}
	}
	return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...