이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize("Ofast","unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e15;
const int SQRT = 450;
struct fenwick{
vector<int> tree;
int n;
fenwick(int n):tree(n+1),n(n){}
int get(int k){
int ans = 0;
while(k){
ans+=tree[k];
k-=k&-k;
}
return ans;
}
void add(int k,int x){
k++;
while(k<=n){
tree[k]+=x;
k+=k&-k;
}
}
int search(int x){
int ans = 0;
for(int bit=16;bit>=0;bit--){
if((ans|(1<<bit))<=n and tree[ans|(1<<bit)]<=x){
ans|=(1<<bit);
x-=tree[ans];
}
}
return ans;
}
};
struct query{
int l,r,silver,gold,idx;
query(int l,int r,int silver,int gold,int idx):l(l),r(r),silver(silver),gold(gold),idx(idx){}
bool operator<(const query& other) const {
return l/SQRT == other.l/SQRT ? r<other.r : l<other.l;
}
};
int32_t main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n,m,q;
cin >> n >> m >> q;
vector<vector<pair<int,int>>> adj(n+1);
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
adj[u].emplace_back(v,i);
adj[v].emplace_back(u,i);
}
vector<vector<int>> checkpointbyidx(n+1);
vector<pair<int,int>> checkpoints(m);
for(auto&[cost,loc]:checkpoints)cin>>loc>>cost;
sort(checkpoints.begin(),checkpoints.end());
for(int i=0;i<m;i++)checkpointbyidx[checkpoints[i].second].emplace_back(i);
vector<int> tour(2*n+1);
vector<int> in(n+1);
vector<int> out(n+1);
vector<int> paridx(n+1);
int idx = 0;
function<void(int,int)> dfs = [&](int x,int p){
tour[++idx]=x;
in[x]=idx;
for(auto&[v,i]:adj[x]){
if(v==p)paridx[x]=i;
else dfs(v,x);
}
tour[++idx]=x;
out[x]=idx;
};
dfs(1,0);
vector<int> ans(q);
vector<query> queries;
for(int i=0;i<q;i++){
int s,t,x,y;cin>>s>>t>>x>>y;
if(out[t]<in[s])queries.emplace_back(out[t],in[s],y,x,i);
else if(out[s]<in[t])queries.emplace_back(out[s],in[t],y,x,i);
else if(out[s]<out[t]) queries.emplace_back(out[s],out[t]-1,y,x,i);
else queries.emplace_back(out[t],out[s]-1,y,x,i);
}
sort(queries.begin(),queries.end());
int l = 1;
int r = 0;
fenwick costchosen(m);
fenwick amtchosen(m);
vector<int> addcnt(n+1);
int totchosen = 0;
auto add = [&](int x){
for(auto&i:checkpointbyidx[x]){
costchosen.add(i,checkpoints[i].first);
amtchosen.add(i,1);
totchosen++;
}
};
auto remove = [&](int x){
for(auto&i:checkpointbyidx[x]){
costchosen.add(i,-checkpoints[i].first);
amtchosen.add(i,-1);
totchosen--;
}
};
auto flip = [&](int x){
if(addcnt[x]&1)remove(x);
else add(x);
addcnt[x]++;
};
for(auto&qu:queries){
while(l<qu.l){
flip(paridx[tour[l++]]);
}
while(qu.l<l){
flip(paridx[tour[--l]]);
}
while(qu.r<r){
flip(paridx[tour[r--]]);
}
while(r<qu.r){
flip(paridx[tour[++r]]);
}
ans[qu.idx] = max(-1ll,qu.gold-totchosen+amtchosen.get(costchosen.search(qu.silver)));
}
for(int&i:ans)cout<<i<<'\n';
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |