QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#303203 | #7563. Fun on Tree | Zeardoe | RE | 0ms | 0kb | C++20 | 6.9kb | 2024-01-11 21:12:44 | 2024-01-11 21:12:44 |
answer
/*
[templates]:
duipai
compre
addhis
floor_sum
matrix
network_flow
polynomial
lca
bitset
valuesgt
fenwick
erbitree
segment
mcmf
primal_dual
centroid
add0cnt
euler
basis
*/
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx")
#include<bits/stdc++.h>
using namespace std;
#define int long long
//use ll instead of int.
#define f(i, a, b) for(int i = (a); i <= (b); i++)
#define cl(i, n) i.clear(),i.resize(n);
#define endl '\n'
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 1e18;
//#define cerr if(false)cerr
//#define freopen if(false)freopen
mt19937 rng(std::chrono::high_resolution_clock::now().time_since_epoch().count());
int rnd(int l, int r) {return rng() % (r-l+1) + l; }
#define watch(x) cerr << (#x) << ' '<<'i'<<'s'<<' ' << x << endl
void pofe(int number, int bitnum) {
string s; f(i, 0, bitnum) {s += char(number & 1) + '0'; number >>= 1; }
reverse(s.begin(), s.end()); cerr << s << endl;
return;
}
double runtime() {return 1.0*clock()/CLOCKS_PER_SEC;}
template <typename TYP> void cmax(TYP &x, TYP y) {if(x < y) x = y;}
template <typename TYP> void cmin(TYP &x, TYP y) {if(x > y) x = y;}
//调不出来给我对拍!
//use std::array.
const int N=200000;
int w[N+10];vector<pii> tr[N+10]; int dis[N+10]; pii dw[N+10],sub[N+10]; int n,q;
int dfn[N+10],dfo[N+10],seq[N+10],deep[N+10],anc[N+10],ding[N+10],sz[N+10],hea[N+10],dcnt;
pii merge(pii x,pii y) {
if(x.first!=y.first)return x.first>y.first?x:y;
return x.second<y.second?x:y;
}
pii operator- (pii x,int y) {return {x.first-y,x.second};}
pii operator+ (pii x,int y) {return {x.first+y,x.second};}
struct SGT {
pii t[N*4+10]; int tag[N*4+10];
void pushdown(int now) {
if(tag[now]!=0){
tag[now*2]+=tag[now];
tag[now*2+1]+=tag[now];
t[now*2].first+=tag[now];
t[now*2+1].first+=tag[now];
tag[now]=0;
}
}
void change(int now,int l,int r,int x,pii k) {
// cerr<<"change("<<now<<", "<<l<<", "<<r<<", "<<x<<", "<<k.first<<" "<<k.second<<")"<<endl;
if(l==r) {t[now]=k;return; }
int mid=(l+r)>>1; pushdown(now);
if(x<=mid)change(now*2,l,mid,x,k);else change(now*2+1,mid+1,r,x,k);
t[now]=merge(t[now*2],t[now*2+1]);
// cerr<<"t["<<now<<"]="<<t[now].first<<" "<<t[now].second<<endl;
}
void build(int now,int l,int r,pii o[]) {
// f(i,1,n)cerr<<o[i].first<<" "<<o[i].second<<endl;
tag[now]=0;
if(l==r) {t[now]=o[l];return;}
int mid=(l+r)>>1; build(now*2,l,mid,o);
build(now*2+1,mid+1,r,o);
t[now]=merge(t[now*2],t[now*2+1]);
}
void add(int now,int l,int r,int x,int y,int k) {
// cerr<<"add("<<now<<", "<<l<<", "<<r<<", "<<x<<", "<<y<<", "<<k<<")"<<endl;
if(l>=x&&r<=y) {t[now].first+=k;tag[now]+=k;return;}
if(l>y||r<x)return;
int mid=(l+r)>>1;pushdown(now);
add(now*2,l,mid,x,y,k);add(now*2+1,mid+1,r,x,y,k);
t[now]=merge(t[now*2],t[now*2+1]);
// cerr<<"t["<<now<<"]="<<t[now].first<<" "<<t[now].second<<endl;
}
pii query(int now,int l,int r,int x,int y) {
// cerr<<"query("<<now<<", "<<l<<", "<<r<<", "<<x<<", "<<y<<") \n";
if(l>=x&&r<=y) {return t[now]; }
if(l>y||r<x) {return {-inf,0}; }
int mid=(l+r)>>1; pushdown(now);
// pii res=merge(query(now*2,l,mid,x,y),query(now*2+1,mid+1,r,x,y));
return merge(query(now*2,l,mid,x,y),
query(now*2+1,mid+1,r,x,y));
}
}sgt[2];
void dfs1(int now,int fa) {
cerr<<"dfs("<<now<<", "<<fa<<") \n";
anc[now]=fa;sz[now]=1;
for(pii iw:tr[now]) {
int i=iw.first,w=iw.second;
if(i!=fa) {
dis[i]=dis[now]+w;
dfs1(i,now);sz[now]+=sz[i];if(sz[i]>sz[hea[now]])hea[now]=i;
}
}
}
void dfs2(int now,int fa) {
dfn[now]=++dcnt;seq[dcnt]=now;
if(hea[fa]==now) {ding[now]=ding[fa],deep[now]=deep[fa];}
else {ding[now]=now,deep[now]=deep[fa]+1;}
if(hea[now])dfs2(hea[now],now);
for(pii iw:tr[now]) {
int i=iw.first,w=iw.second;
if(i!=fa&&i!=hea[now]) {
dfs2(i,now);
}
}
dfo[now]=dcnt;
}
void change(int x,int w) {
sgt[0].add(1,1,n,dfn[x],dfo[x],-w);
sgt[1].add(1,1,n,dfn[x],dfo[x],-w);
while(deep[x]>1) {
x=anc[ding[x]];
pii tmp=merge(sgt[0].query(1,1,n,dfn[x],dfn[hea[x]]-1),
sgt[0].query(1,1,n,dfo[hea[x]]+1,dfo[x]))-2*dis[x];
// cerr<<"change:"<<x<<" "<<tmp.first<<" "<<tmp.second<<endl;
sgt[1].change(1,1,n,dfn[x],tmp);
}
}
void findans(int x) {
// cerr<<"findans: "<<x<<endl;
pii ans={-inf,0};
pii tmp1=sgt[0].query(1,1,n,dfn[x],dfo[x])-2*dis[x]+dis[x];
ans=merge(ans,tmp1);
// cerr<<"tmp1:"<<tmp1.first<<" "<<tmp1.second<<endl;
int ix=x;
while(deep[x]>=1) {
pii tmp=sgt[1].query(1,1,n,dfn[ding[x]],dfn[x]-1)+dis[ix];
// cerr<<"query:"<<dfn[ding[x]]<<", "<<dfn[x]-1<<endl;
// cerr<<"tmp:"<<tmp.first<<" "<<tmp.second<<endl;
cmax(ans,tmp);
if(deep[x]>1) {
pii tmp2=merge(sgt[0].query(1,1,n,dfn[anc[ding[x]]],dfn[ding[x]]-1),
sgt[0].query(1,1,n,dfo[ding[x]]+1,dfo[anc[ding[x]]]))-2*dis[x]+dis[ix];
ans=(ans,tmp2);
}
x=anc[ding[x]];
}
cout<<ans.second<<" "<<ans.first<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(NULL);
cout.tie(NULL);
freopen("QOJ7563.in","r",stdin);
freopen("QOJ7563.out","w",stdout);
freopen("QOJ7563.ear","w",stderr);
//time_t start = clock();
//think twice,code once.
//think once,debug forever.
cin>>n>>q;
f(i,1,n)cin>>w[i];
f(i,2,n) {int u,v,ww;u=i;cin>>v>>ww;tr[u].push_back({v,ww});tr[v].push_back({u,ww});}
dfs1(1,0); dfs2(1,0);
// cerr<<"hea: ";f(i,1,n)cerr<<hea[i]<<" \n"[i==n];
// cerr<<"dfn: ";f(i,1,n)cerr<<dfn[i]<<" \n"[i==n];
// cerr<<"ding: ";f(i,1,n)cerr<<ding[i]<<" \n"[i==n];
// cerr<<"seq: ";f(i,1,n)cerr<<seq[i]<<" \n"[i==n];
f(i,1,n)dw[i]={dis[seq[i]]-w[seq[i]],seq[i]};
sgt[0].build(1,1,n,dw);
f(i,1,n){
if(hea[seq[i]])sub[i]=merge(sgt[0].query(1,1,n,i,dfn[hea[seq[i]]]-1),
sgt[0].query(1,1,n,dfo[hea[seq[i]]]+1,dfo[seq[i]]))-2*dis[i];
else sub[i]={dis[seq[i]]-w[seq[i]]-2*dis[seq[i]],seq[i]};
}
sgt[1].build(1,1,n,sub);
// cerr<<"dw: ";f(i,1,n)cerr<<dw[i].first<<" \n"[i==n];
// cerr<<"sub: ";f(i,1,n)cerr<<sub[i].first<<" \n"[i==n];
f(i,1,q) {
int x,y,z;cin>>x>>y>>z;
change(y,z);
findans(x);
}
//time_t finish = clock();
//cout << "time used:" << (finish-start) * 1.0 / CLOCKS_PER_SEC <<"s"<< endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Dangerous Syscalls
input:
6 6 1 1 4 5 1 4 1 5 2 0 3 2 4 1 5 6 3 2 -100000 1 2 100000 1 1 0 2 2 66 3 1 5 4 4 -3