제출 #730487

#제출 시각아이디문제언어결과실행 시간메모리
730487kymTwo Currencies (JOI23_currencies)C++14
100 / 100
1180 ms250720 KiB
#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define FOR(i,s,e) for(int i = s; i <= (int)e; ++i)
#define DEC(i,s,e) for(int i = s; i >= (int)e; --i)
#define IAMSPEED ios_base::sync_with_stdio(false); cin.tie(0);
#ifdef LOCAL
#define db(x) cerr << #x << "=" << x << "\n"
#define db2(x, y) cerr << #x << "=" << x << " , " << #y << "=" << y << "\n"
#define db3(a,b,c) cerr<<#a<<"="<<a<<","<<#b<<"="<<b<<","<<#c<<"="<<c<<"\n"
#define dbv(v) cerr << #v << ":"; for (auto ite : v) cerr << ite << ' '; cerr <<"\n"
#define dbvp(v) cerr << #v << ":"; for (auto ite : v) cerr << "{"  << ite.f << ',' << ite.s << "} "; cerr << "\n"
#define dba(a,ss,ee) cerr << #a << ":"; FOR(ite,ss,ee) cerr << a[ite] << ' '; cerr << "\n"
#define reach cerr << "LINE: " << __LINE__ << "\n";
#else
#define reach 
#define db(x)
#define db2(x,y)
#define db3(a,b,c)
#define dbv(v)
#define dbvp(v)
#define dba(a,ss,ee)
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define f first 
#define s second
#define g0(x) get<0>(x)
#define g1(x) get<1>(x)
#define g2(x) get<2>(x)
#define g3(x) get<3>(x)
typedef pair <int, int> pi;
typedef tuple<int,int,int> ti3;
typedef tuple<int,int,int,int> ti4;
int rand(int a, int b) { return a + rng() % (b-a+1); }
const int MOD = 1e9 + 7;
const int inf = (int)1e9 + 500;
const long long oo = (long long)1e18 + 500;
template <typename T> void chmax(T& a, const T b) { a=max(a,b); }
template <typename T> void chmin(T& a, const T b) { a=min(a,b); }
const int MAXN = 1000005;
int n,m,q;
vector<int>V[MAXN];
vector<pi> adj[MAXN];
int P[MAXN];
int head[MAXN];
int heavy[MAXN];
int pos[MAXN];
int parent[MAXN];
int depth[MAXN];
int sz[MAXN];
int cnt=1;
vector<int> W[MAXN];
int dfs(int x, int p){ 
	sz[x]=1;
	parent[x]=p;
	int mx=0;
	for(auto v:adj[x])if(v.f!=p){
		depth[v.f]=depth[x]+1;
		int res=dfs(v.f,x);
		W[v.f]=V[v.s];
		if(res>mx){
			mx=res;
			heavy[x]=v.f;
		}
		sz[x]+=res;
	}
	return sz[x];
}

void decompose(int x, int h) {
	pos[x]=cnt++;
	head[x]=h;
	if(heavy[x]!=-1)decompose(heavy[x],h);
	for(auto v:adj[x]){
		if(v.f==parent[x]||v.f==heavy[x])continue;
		decompose(v.f,v.f);
	}
}

struct node {
	node *l=nullptr,*r=nullptr;
	int sum;
	int num;
	int s,e,m;
	node(int _s, int _e, int val,int numval) {
		s=_s;e=_e;
		m=(s+e)/2;
		sum=val;
		num=numval;
		return;
	}
	node(int _s, int _e, node *L, node *R) {
		s=_s;e=_e;m=(s+e)/2;
		l=L;
		r=R;
		sum=0;
		num=0;
		if(l)sum+=l->sum;
		if(r)sum+=r->sum;
		if(l)num+=l->num;
		if(r)num+=r->num;
	}
} *roots[MAXN];

node* build(int tl, int tr){
	if(tl==tr){
		return new node(tl,tr,(int)0,(int)0);
	}
	int tm=(tl+tr)/2;
	return new node(tl,tr,build(tl,tm), build(tm+1,tr));
}

node* update(node *v, int tl, int tr, int pos, int nval) {
	if(tl==tr){
		return new node(tl,tr,v->sum+nval,v->num+1);
	}
	int tm=(tl+tr)/2;
	if(pos<=tm){
		return new node(tl,tr,update(v->l,tl,tm,pos,nval),v->r);
	} else{
		return new node(tl,tr,v->l,update(v->r,tm+1,tr,pos,nval));
	}
}

pi E[MAXN];
map<int,int> D;
map<int,int> R;
void discretize(vector<int> vec){
	vector<int> dis=vec;
	sort(all(dis));
	dis.resize(unique(all(dis))-dis.begin());
	FOR(i,0,vec.size()-1){
		D[vec[i]]=lower_bound(all(dis),vec[i])-dis.begin()+1;
		R[lower_bound(all(dis),vec[i])-dis.begin()+1]=vec[i];
	}
}
vector<pair<node*,node*>> nodes;
void ask(int x, int y) {
	for(;head[x]!=head[y];y=parent[head[y]]){
		if(depth[head[x]]>depth[head[y]])swap(x,y);
		nodes.pb({roots[pos[head[y]]-1],roots[pos[y]]});
	}
	if(x==y)return;
	if(depth[x]>depth[y])swap(x,y);
	nodes.pb({roots[pos[x]],roots[pos[y]]});
}
int32_t main() 
{
	IAMSPEED
	memset(heavy,-1,sizeof heavy);
	cin >> n >> m >> q;
	FOR(i,1,n-1){
		cin >> E[i].f >> E[i].s;
	}
	vector<int> disc;
	FOR(i,1,m){
		int x; cin >> x;
		int cost; cin>>cost;
		disc.pb(cost);
		V[x].pb(cost);
	}
	discretize(disc);
	FOR(i,1,n-1){
		adj[E[i].f].pb({E[i].s,i}); // this is the edge index
		adj[E[i].s].pb({E[i].f,i}); // this is the edge index
	}
	dfs(1,-1);
	decompose(1,1);
	vector<pi> vec;
	FOR(i,2,n){
		vec.pb({pos[i],i});
	}
	sort(all(vec));
	roots[1]=build(0,m+5);
	for(auto x:vec) {
		roots[x.f]=roots[x.f-1];
		//db(x.s);
		//dbv(W[x.s]);
		for(auto cost:W[x.s]){
			roots[x.f]=update(roots[x.f],0,m+5,D[cost],cost);
		}
		
	}
	while(q--){
		nodes.clear();
		int s,t,x,y; cin >> s >> t >> x >> y;
		ask(s,t);
		for(auto &x:nodes){
			node* lf=x.f;
			node* rg=x.s;
		}
		vector<pair<node*,node*>> V=nodes;
		bool done=0;
		int res=0;
		int val=0;
		int num=0;
		int S,E;
		while(!done){
			
			int lfsum=0;
			int lfnum=0;

			for(auto &x:nodes){
				node* lf=x.f;
				node* rg=x.s;

				S=lf->s;
				E=lf->e;

				if(lf->s==lf->e){
					done=1;
					res=lf->s;
					break;
				}
				lfsum+=rg->l->sum - lf->l->sum;
				lfnum+=rg->l->num - lf->l->num;
			}
			if(val+lfsum<=y){
				val+=lfsum;
				num+=lfnum;

				for(auto &x:nodes){
					x.f=x.f->r;
					x.s=x.s->r;
				}
			} else {
				for(auto &x:nodes){
					x.f=x.f->l;
					x.s=x.s->l;
				}
			}
		}
		//
		// it ended at res. hence, we might be able to get some of res+1 also. 
		--res;
		int extra=0;
		if(R[res+1])extra=(y-val)/R[res+1];
		int ss=num+extra;
		int tot = 0;
		for(auto &x:V){
			node* lf=x.f;
			node* rg=x.s;
			tot+=rg->num-lf->num;
		}
		int spend=tot-ss;
		assert(spend>=0);
		if(spend>x){
			cout<<-1<<'\n';
		} else{
			cout<<x-spend<<'\n';
		}
	}
}



컴파일 시 표준 에러 (stderr) 메시지

currencies.cpp: In function 'int32_t main()':
currencies.cpp:192:10: warning: unused variable 'lf' [-Wunused-variable]
  192 |    node* lf=x.f;
      |          ^~
currencies.cpp:193:10: warning: unused variable 'rg' [-Wunused-variable]
  193 |    node* rg=x.s;
      |          ^~
currencies.cpp:200:7: warning: variable 'S' set but not used [-Wunused-but-set-variable]
  200 |   int S,E;
      |       ^
currencies.cpp:200:9: warning: variable 'E' set but not used [-Wunused-but-set-variable]
  200 |   int S,E;
      |         ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...