제출 #1332300

#제출 시각아이디문제언어결과실행 시간메모리
1332300boclobanchat사탕 분배 (IOI21_candies)C++20
0 / 100
667 ms42412 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;
	pair<long long,long long> val;
};
long long lazy[MAXN*4],fen[MAXN],cv[MAXN],sum=0;
pair<long long,long long> seg[MAXN*4];
int type[MAXN];
vector<query> vq[MAXN];
pair<long long,long long> operator+(const pair<long long,long long>& a,const pair<long long,long long>& b)
{
	return {max(a.first,b.first),min(a.second,b.second)};
}
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]={-INF,INF};
	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];
	seg[pos*2].first+=val,seg[pos*2].second+=val,lazy[pos*2]+=val;
	seg[pos*2+1].first+=val,seg[pos*2+1].second+=val,lazy[pos*2+1]+=val;
	lazy[pos]=0;
}
void updset(int l,int r,int i,pair<long long,long long> val,int pos)
{
	if(i<l||r<i) return ;
	if(l==r)
	{
		seg[pos]=val;
		return ;
	}
	int mid=(l+r)/2;
	down(pos);
	updset(l,mid,i,val,pos*2);
	updset(mid+1,r,i,val,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)
	{
		seg[pos]={seg[pos].first+val,seg[pos].second+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];
}
pair<long long,long long> getidx(int l,int r,int i,int pos)
{
	if(l==r) return seg[pos];
	int mid=(l+r)/2;
	down(pos);
	if(i<=mid) return getidx(l,mid,i,pos*2);
	return getidx(mid+1,r,i,pos*2+1);
}
int walk(int l,int r,pair<long long,long long> val,long long c,int pos)
{
	if(l==r) return l+1;
	int mid=(l+r)/2;
	down(pos);
	pair<long long,long long> res=val+seg[pos*2+1];
	if(res.first-res.second<=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].first-seg[1].second<=c) return 0;
	return walk(0,n,{-INF,INF},c,1);
}
void updidx(int i,int n,pair<long long,long long> val)
{
	if(val.first==-INF)
	{
		sum-=cv[i],type[i]=0;
		updf(i+1,n+1,-cv[i]);
		updset(0,n,i,val,1);
		update(0,n,i,n,cv[i],1);
	}
	else
	{
		if(val.first>=0) type[i]=1;
		else type[i]=-1;
		sum+=(cv[i]=val.first);
		updf(i+1,n+1,cv[i]);
		updset(0,n,i,{0,0},1);
		update(0,n,i,i,-getf(i+1),1);
		update(0,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,{v[i],v[i]}});
		vq[r[i]+1].push_back({i+1,{-INF,INF}});
	}
	build(0,q,1);
	for(int i=0;i<n;i++)
	{
		updidx(0,q,{0,-c[i]});
		for(auto v:vq[i]) updidx(v.idx,q,v.val);
		int pos=walk(q,c[i]);
		pair<long long,long long> curr=getidx(0,q,pos,1);
		if(type[pos]!=1) ans.push_back(curr.first+sum);
		else ans.push_back(curr.second+sum+c[i]);
	}
	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...