제출 #994166

#제출 시각아이디문제언어결과실행 시간메모리
994166bachhoangxuanJOI tour (JOI24_joitour)C++17
100 / 100
1707 ms102156 KiB
#include "joitour.h" #include<bits/stdc++.h> using namespace std; using i32 = int; #define int long long const int maxn = 2e5+5; int N,C[maxn]; vector<int> edge[maxn]; int L[maxn],R[maxn],T,ans,P[maxn]; int child[maxn],son[maxn],head[maxn],lst[maxn],par[maxn]; void pre_dfs(int u,int p){ child[u]=1;par[u]=p; for(int v:edge[u]){ if(v==p) continue; pre_dfs(v,u); child[u]+=child[v]; if(child[v]>child[son[u]]) son[u]=v; } } void hld_dfs(int u,int p,int t){ L[u]=++T;P[T]=u; if(t) head[u]=head[p]; else head[u]=u; //cout << "head " << u << ' ' << head[u] << ' ' << head[p] << '\n'; lst[head[u]]=u; if(son[u]) hld_dfs(son[u],u,1); for(int v:edge[u]) if(v!=p && v!=son[u]) hld_dfs(v,u,0); R[u]=T; } struct Node{ int s0=0,s2=0,c0=0,c2=0; int sum=0,total=0; Node(int s0=0,int s2=0,int c0=0,int c2=0):s0(s0),s2(s2),c0(c0),c2(c2){ sum=c0*c2; } friend Node operator+(Node a,Node b){ Node res; res.s0=a.s0+b.s0; res.s2=a.s2+b.s2; res.c0=a.c0+b.c0; res.c2=a.c2+b.c2; res.sum=a.sum+b.sum; res.total=a.total+b.total+a.c0*b.s2+a.c2*b.s0+a.s0*b.c2+a.s2*b.c0; return res; }; friend Node operator-(Node a,Node b){ Node res; res.s0=a.s0-b.s0; res.s2=a.s2-b.s2; res.c0=a.c0-b.c0; res.c2=a.c2-b.c2; res.sum=a.sum-b.sum; res.total=a.total-b.total-(res.c0*b.s2+res.c2*b.s0+res.s0*b.c2+res.s2*b.c0); return res; }; }cc[maxn]; struct node{ int total=0; int c0=0,c1=0,c2=0; int l0=0,l2=0,r0=0,r2=0; node(){} friend node operator+(node a,node b){ node res; res.c0=a.c0+b.c0; res.c1=a.c1+b.c1; res.c2=a.c2+b.c2; res.l0=a.l0+b.l0+a.c0*b.c1; res.l2=a.l2+b.l2+a.c2*b.c1; res.r0=a.r0+b.r0+a.c1*b.c0; res.r2=a.r2+b.r2+a.c1*b.c2; res.total=a.total+b.total+a.l0*b.c2+a.l2*b.c0+a.c0*b.r2+a.c2*b.r0; return res; } }tree[4*maxn]; node query(int l,int r,int id,int tl,int tr){ if(tr<l || r<tl) return node(); if(tl<=l && r<=tr) return tree[id]; int mid=(l+r)>>1; return query(l,mid,id<<1,tl,tr)+query(mid+1,r,id<<1|1,tl,tr); } void update(int l,int r,int id,int p,node val){ if(l==r){ tree[id]=val; return; } int mid=(l+r)>>1; if(p<=mid) update(l,mid,id<<1,p,val); else update(mid+1,r,id<<1|1,p,val); tree[id]=tree[id<<1]+tree[id<<1|1]; } void change(i32 u, i32 d) { //cout << "change " << u << ' ' << d << '\n'; u++;C[u]=d; while(u){ int v=head[u],w=lst[v],p=par[v]; //cout << u << ' ' << v << ' ' << w << '\n'; node cur=query(1,N,1,L[v],L[w]); ans-=cur.total; if(p) cc[p]=cc[p]-Node(cur.r0,cur.r2,cur.c0,cur.c2); node val; val.total=cc[u].total; val.l0=val.r0=cc[u].s0; val.l2=val.r2=cc[u].s2; val.c0=cc[u].c0; val.c2=cc[u].c2; node add; if(C[u]==0) add.c0++; else if(C[u]==2) add.c2++; else{ add.c1++; add.total+=cc[u].c0*cc[u].c2-cc[u].sum; } val=val+add; //cout << val.c0 << ' ' << val.c1 << ' ' << val.c2 << ' ' << val.l0 << ' ' << val.l2 << ' ' << val.r0 << ' ' << val.r2 << ' ' << val.total << '\n'; val.l0=val.r0=max(val.l0,val.r0); val.l2=val.r2=max(val.l2,val.r2); update(1,N,1,L[u],val); cur=query(1,N,1,L[v],L[w]); ans+=cur.total; if(p) cc[p]=cc[p]+Node(cur.r0,cur.r2,cur.c0,cur.c2); u=p; } } void init(i32 _N, std::vector<i32> F, std::vector<i32> U, std::vector<i32> V, i32 Q) { N=_N; for(int i=0;i<N-1;i++){ U[i]++;V[i]++; edge[U[i]].push_back(V[i]); edge[V[i]].push_back(U[i]); } pre_dfs(1,0); hld_dfs(1,0,0); for(int i=1;i<=N;i++){ int u=P[i]; change(u-1,F[u-1]); } } long long num_tours() { return ans; } #undef int
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...