QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#124065 | #5439. Meet in the Middle | TadijaSebez | WA | 59ms | 61556kb | C++14 | 5.0kb | 2023-07-14 05:55:22 | 2023-07-14 05:55:24 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int N=200050;
const int L=19;
const ll inf=1e18;
struct CentroidTree{
vector<pair<int,int>> E[N],G[N];
bool was[N],clean[N];
int sz[N],cenPar[N],cenDep[N],tsz;
ll dep[N][L];
int where[N][L];
ll mx[N][3];
vector<int> dirty;
CentroidTree(){
for(int i=0;i<N;i++){
was[i]=false;
sz[i]=0;
cenPar[i]=0;
cenDep[i]=0;
for(int j=0;j<L;j++){
dep[i][j]=0;
}
E[i].clear();
}
dirty.clear();
}
void AddEdge(int u,int v,int w){
G[u].pb({v,w});
G[v].pb({u,w});
}
void AddEdge2(int u,int v,int w){
E[u].pb({v,w});
E[v].pb({u,w});
}
void DFSSZ(int u,int p){
sz[u]=1;
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p){
DFSSZ(v,u);
sz[u]+=sz[v];
}
}
}
int Find(int u,int p,int n){
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p&&sz[v]*2>=n){
return Find(v,u,n);
}
}
return u;
}
int Find(int u){
DFSSZ(u,u);
return Find(u,u,sz[u]);
}
void DFSDEP(int u,int p,int lvl,ll w,int cnt){
dep[u][lvl]=w;
where[u][lvl]=cnt;
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p){
DFSDEP(v,u,lvl,w+e.second,cnt);
}
}
}
void EXP(int u,int p){
vector<pair<int,int>> es;
for(auto e:G[u]){
if(e.first!=p){
EXP(e.first,u);
es.pb(e);
}
}
if(es.size()<=2){
for(auto e:es){
AddEdge2(u,e.first,e.second);
}
}else{
int node=u;
for(int i=0;i+1<es.size();i++){
AddEdge2(node,es[i].first,es[i].second);
if(i+2==es.size()){
AddEdge2(node,es[i+1].first,es[i+1].second);
}else{
++tsz;
AddEdge2(node,tsz,0);
node=tsz;
}
}
}
}
void Expand(int n){
tsz=n;
EXP(1,0);
}
void Build(int u=1, int lvl=0){
u=Find(u);
was[u]=true;
cenDep[u]=lvl;
mx[u][0]=-inf;
mx[u][1]=-inf;
mx[u][2]=-inf;
clean[u]=true;
int cnt=0;
for(auto e:E[u]){
int v=e.first;
if(!was[v]){
DFSDEP(v,u,lvl,e.second,cnt);
cnt++;
}
}
for(auto e:E[u]){
int v=e.first;
if(!was[v]){
Build(v,lvl+1);
cenPar[v]=u;
}
}
}
void Set(int u,ll w){
//printf("Set u:%i w:%lld\n",u,w);
for(int cen=u;cen;cen=cenPar[cen]){
int lvl=cenDep[cen];
if(u==cen){
for(int j=0;j<3;j++){
mx[cen][j]=max(mx[cen][j],w+dep[u][lvl]);
}
}else{
mx[cen][where[u][lvl]]=max(mx[cen][where[u][lvl]],w+dep[u][lvl]);
}
if(clean[cen]){
clean[cen]=false;
dirty.pb(cen);
}
}
}
void Reset(){
//printf("Reset\n");
for(int u:dirty){
clean[u]=true;
mx[u][0]=-inf;
mx[u][1]=-inf;
mx[u][2]=-inf;
}
dirty.clear();
}
ll Get(int u){
ll ans=-inf;
for(int cen=u;cen;cen=cenPar[cen]){
int lvl=cenDep[cen];
for(int j=0;j<3;j++){
if(j==where[u][lvl] && u!=cen)continue;
ans=max(ans,mx[cen][j]+dep[u][lvl]);
}
}
return ans;
}
};
CentroidTree tree;
vector<pair<int,int>> E[N];
vector<pair<int,int>> Qs[N];
ll ans[N];
bool was[N];
int sz[N];
void DFSSZ(int u,int p){
sz[u]=1;
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p){
DFSSZ(v,u);
sz[u]+=sz[v];
}
}
}
int Find(int u,int p,int n){
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p&&sz[v]*2>=n){
return Find(v,u,n);
}
}
return u;
}
int Find(int u){
DFSSZ(u,u);
return Find(u,u,sz[u]);
}
void DFSDEP(int u,int p,int lvl,ll w){
tree.Set(u,w);
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p){
DFSDEP(v,u,lvl,w+e.second);
}
}
}
void Solve(int u,int p,int lvl,ll w){
for(auto q:Qs[u]){
//printf("u:%i v:%i lvl:%i w:%lld get:%lld\n",u,q.first,lvl,w,tree.Get(q.first));
ans[q.second]=max(ans[q.second],tree.Get(q.first)+w);
}
for(auto e:E[u]){
int v=e.first;
if(!was[v]&&v!=p){
Solve(v,u,lvl,w+e.second);
}
}
}
void Decompose(int u,int lvl=0){
u=Find(u);
was[u]=true;
tree.Set(u,0);
for(auto e:E[u]){
int v=e.first;
if(!was[v]){
Solve(v,u,lvl,e.second);
DFSDEP(v,u,lvl,e.second);
}
}
for(auto q:Qs[u]){
//printf("u:%i v:%i lvl:%i w:%lld get:%lld\n",u,q.first,lvl,0,tree.Get(q.first));
ans[q.second]=max(ans[q.second],tree.Get(q.first));
}
tree.Reset();
reverse(E[u].begin(),E[u].end());
tree.Set(u,0);
for(auto e:E[u]){
int v=e.first;
if(!was[v]){
Solve(v,u,lvl,e.second);
DFSDEP(v,u,lvl,e.second);
}
}
tree.Reset();
for(auto e:E[u]){
int v=e.first;
if(!was[v]){
Decompose(v,lvl+1);
}
}
}
int main(){
int n,q;
scanf("%i %i",&n,&q);
for(int i=1;i<n;i++){
int u,v,w;
scanf("%i %i %i",&u,&v,&w);
tree.AddEdge(u,v,w);
}
tree.Expand(n);
tree.Build();
for(int i=1;i<n;i++){
int u,v,w;
scanf("%i %i %i",&u,&v,&w);
E[u].pb({v,w});
E[v].pb({u,w});
}
for(int i=1;i<=q;i++){
int u,v;
scanf("%i %i",&u,&v);
Qs[v].pb({u,i});
ans[i]=-inf;
}
Decompose(1);
for(int i=1;i<=q;i++){
printf("%lld\n",ans[i]);
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 5ms
memory: 58964kb
input:
3 4 1 2 1 2 3 2 1 2 2 2 3 1 1 1 1 2 2 1 2 2
output:
6 4 5 3
result:
ok 4 number(s): "6 4 5 3"
Test #2:
score: 0
Accepted
time: 1ms
memory: 58964kb
input:
2 1 1 2 1 1 2 1 1 1
output:
2
result:
ok 1 number(s): "2"
Test #3:
score: 0
Accepted
time: 0ms
memory: 58980kb
input:
2 1 1 2 1 1 2 1 1 2
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: -100
Wrong Answer
time: 59ms
memory: 61556kb
input:
10000 50000 8101 5996 108427744 5996 7605 870838849 5996 5599 603303696 8101 3006 339377417 8101 6463 442516687 6463 5560 109174079 5560 4063 127596224 3006 1682 947915262 5996 1986 130416311 6463 5455 279771516 6463 2634 516688796 4063 3034 217886863 7605 5092 742375061 5599 2266 193804402 5092 140...
output:
281548625600 83465423738 173974174344 221115177602 193611563902 207123322783 167879226893 209476971066 275239899409 209470650886 323546988017 38372376672 58017805887 139931696314 249858649505 151416604919 163775968184 331809274076 235476703077 128813896485 117053976352 122164625564 163825768790 2332...
result:
wrong answer 1st numbers differ - expected: '647838384844', found: '281548625600'