QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#26809#2564. Two TreesIrisuWA 3ms31388kbC++146.1kb2022-04-08 15:05:242022-04-29 04:31:42

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-04-29 04:31:42]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:31388kb
  • [2022-04-08 15:05:24]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(a),i##end=(b);i<=i##end;++i)
#define per(i,a,b) for(int i=(a),i##end=(b);i>=i##end;--i)
mt19937 Rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
template<typename T>void chkmax(T&x,T y){if(x<y)x=y;}
template<typename T>void chkmin(T&x,T y){if(x>y)x=y;}

#define pb push_back
#define ALL(x) (x).begin(),(x).end()
#define mem(x) memset((x),0,sizeof(x))

typedef double db;
typedef long long ll;
typedef vector<int>vi;
typedef pair<int,int>pii;

typedef unsigned u32;
typedef unsigned uint;
typedef unsigned long long u64;

namespace orzjk{
  const int SZ=1e6;
  char buf[SZ],*p1=buf,*p2=buf;
  char nc(){
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,SZ,stdin),p1==p2)?EOF:*p1++;
  }
  char fub[SZ],*p3=fub,*p4=fub+SZ;
  void pc(char c){
    p3==p4&&(fwrite(fub,1,SZ,stdout),p3=fub);
    *p3++=c;
  }
  void flush(){
    fwrite(fub,1,p3-fub,stdout),p3=fub;
  }
}
using orzjk::nc;
using orzjk::pc;

//#define nc getchar
//#define pc putchar

int read(){
  int x=0,f=1;char c=nc();
  while(c<48)c=='-'&&(f=-1),c=nc();
  while(c>47)x=x*10+(c^48),c=nc();
  return x*f;
}
void write(int x){
  static char st[21];
  if(!x)return pc(48),void();
  char*p=st;
  if(x<0)x=-x,pc('-');
  for(;x;x/=10)*p++=x%10|48;
  do{
    pc(*--p);
  }while(p!=st);
}

//const int P=1e9+7;
const int P=998244353;
int qp(int a,int k){
  int res=1;for(;k;k>>=1,a=1ll*a*a%P)if(k&1)res=1ll*res*a%P;return res;
}

const int maxn=1e5+10;
int n;uint ans;

namespace T2{

struct edge{
  int u,v;
}G[maxn];

vi E[maxn];int deg[maxn];

int lg[maxn];
pii st[17][maxn];
int dep[maxn],dfn[maxn],seq[maxn];
uint sz[maxn],F1[maxn],F2[maxn],G1[maxn],G2[maxn];
void dfs1(int u,int f){
  static int now;
  st[0][now]={dfn[f],f},dfn[u]=++now,seq[now]=u;
  sz[u]=1,dep[u]=dep[f]+1;
  for(int v:E[u])if(v!=f){
    dfs1(v,u),sz[u]+=sz[v];
    F1[u]+=F1[v]+sz[v];
    F2[u]+=F2[v]+2*F1[v]+sz[v];
  }
}
void dfs2(int u,int f){
//  printf("(%u %u) (%u %u)\n",F1[u],F2[u],G1[u],G2[u]);
  ans+=G2[u];
  for(int v:E[u])if(v!=f){
    G1[v]=G1[u]-sz[v]+(n-sz[v]);
    G2[v]=G2[u]-2*F1[v]-sz[v]+2*(G1[u]-F1[v]-sz[v])+n-sz[v];
    dfs2(v,u);
  }
}
int qlca(int u,int v){
  if(u==v)return u;
  u=dfn[u],v=dfn[v];
  if(u>v)swap(u,v);
  int k=lg[v-u];pii*seq=st[k];
  return min(seq[u],seq[v-(1<<k)]).second;
}

void init(){
  rep(i,1,n-1){
    int u=read(),v=read();
    G[i]={u,v},deg[u]++,deg[v]++;
  }
  rep(i,1,n)E[i].reserve(deg[i]);
  rep(i,1,n-1){
    int u=G[i].u,v=G[i].v;
    E[u].pb(v),E[v].pb(u);
  }
  dfs1(1,0);
  G1[1]=F1[1],G2[1]=F2[1];
  dfs2(1,0);
//  rep(i,1,n)printf("%d%c",dfn[i],"\n "[i<iend]);
//  rep(i,1,n)printf("(%d %d)%c",st[0][i].first,st[0][i].second,"\n "[i<n]);
  rep(i,2,n)lg[i]=lg[i>>1]+1;
  rep(i,1,16)rep(j,1,n-(1<<i))st[i][j]=min(st[i-1][j],st[i-1][j+(1<<(i-1))]);
}

}

namespace virT{

uint coef,D[maxn];

int ecnt,h[maxn];
struct edge{
  int nxt,to,w;
}E[maxn];
void addline(int u,int v){
  using T2::dep;
//  printf("(%d %d)\n",u,v);
  E[++ecnt]={h[u],v,dep[v]-dep[u]},h[u]=ecnt;
}

uint sz[maxn],F[maxn],G[maxn];
void dfs1(int u){
  F[u]=0,sz[u]=1;
  for(int i=h[u];i;i=E[i].nxt){
    int v=E[i].to;
    dfs1(v),sz[u]+=sz[v],F[u]+=F[v]+E[i].w*sz[v];
  }
//  printf("!%d, %d\n",u,F[u]);
}

void dfs2(int u){
  for(int i=h[u];i;i=E[i].nxt){
    int v=E[i].to;
    G[v]=G[u]+E[i].w*(n-2*sz[v]);
    dfs2(v);
  }
}

void calc(vi&V,uint coef){
  virT::coef=coef;
  using T2::sz;
  using T2::dfn;
  using T2::qlca;
  sort(ALL(V),[](int x,int y){
    return dfn[x]<dfn[y];
  });
  static int dat[maxn];
  int len=V.size();
  rep(i,1,len)dat[i]=V[i-1];
  rep(i,1,len-1)dat[len+i]=qlca(dat[i],dat[i+1]);
  len+=len-1;
  sort(dat+1,dat+len+1,[](int x,int y){
    return dfn[x]<dfn[y];
  });
  len=unique(dat+1,dat+len+1)-dat-1;
  static int st[maxn];
  int top=0;
//  puts("GG");
  rep(_,1,len){
    int u=dat[_];h[u]=0;
    while(top&&dfn[st[top]]+(int)sz[st[top]]<=dfn[u])top--;
    if(top)addline(st[top],u);
    st[++top]=u;
  }
//  printf("!!%d\n",len);
  dfs1(st[1]);
  G[st[1]]=F[st[1]];
  dfs2(st[1]);
  for(int u:V)ans+=2*coef*D[u]*G[u];
//  puts("GG");
}

}

namespace T1{

using virT::D;

struct edge{
  int u,v;
}G[maxn];

vi E[maxn];int deg[maxn];

uint sz[maxn],F1[maxn],F2[maxn],G1[maxn],G2[maxn];
void dfs1(int u,int f){
  sz[u]=1;
  for(int v:E[u])if(v!=f){
    dfs1(v,u),sz[u]+=sz[v];
    F1[u]+=F1[v]+sz[v];
    F2[u]+=F2[v]+2*F1[v]+sz[v];
  }
}
void dfs2(int u,int f){
  ans+=G2[u];
  for(int v:E[u])if(v!=f){
    G1[v]=G1[u]-sz[v]+(n-sz[v]);
    G2[v]=G2[u]-2*F1[v]-sz[v]+2*(G1[u]-F1[v]-sz[v])+n-sz[v];
    dfs2(v,u);
  }
}

bool vis[maxn];
uint sck,sumsz;
void dfs3(int u,int f){
  sumsz++,sz[u]=1;
  for(int v:E[u])if(v!=f&&!vis[v]){
    dfs3(v,u),sz[u]+=sz[v];
  }
}
void dfs4(int u,int f){
  uint s=sumsz-sz[u];
  for(int v:E[u])if(v!=f&&!vis[v]){
    dfs4(v,u),chkmax(s,sz[v]);
  }
  if(s*2<=sumsz)sck=u;
}
int bl[maxn];
vi nod,vec[maxn];
void dfs5(int u,int f){
  if(bl[u]==u)vec[u].clear();
  nod.push_back(u);
  vec[bl[u]].push_back(u);
  for(int v:E[u])if(v!=f&&!vis[v]){
    bl[v]=f?bl[u]:v,D[v]=D[u]+1,dfs5(v,u);
  }
}
void divide(int rt){
//  printf("!%d\n",rt);
  sumsz=0,dfs3(rt,0),dfs4(rt,0),rt=sck;
//  printf("#%d\n",rt);
  bl[rt]=rt,nod.clear(),D[rt]=0,dfs5(rt,0);
  virT::calc(nod,1);
  for(int v:E[rt])if(!vis[v])virT::calc(vec[v],-1);
  vis[rt]=1;
  for(int v:E[rt])if(!vis[v]){
    divide(v);
  }
}

void init(){
  rep(i,1,n-1){
    int u=read(),v=read();
    G[i]={u,v},deg[u]++,deg[v]++;
  }
  rep(i,1,n)E[i].reserve(deg[i]);
  rep(i,1,n-1){
    int u=G[i].u,v=G[i].v;
    E[u].pb(v),E[v].pb(u);
  }
  dfs1(1,0);
  G1[1]=F1[1],G2[1]=F2[1];
  dfs2(1,0);
}

}

void solve(){
  n=read();
  T1::init();
  T2::init();
  ans/=2;
  T1::divide(1);
  cout<<ans<<endl;
}

signed main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
//  int T;cin>>T;while(T--)solve();
  solve();
  orzjk::flush();
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 26304kb

input:

3
1 2
1 3
1 2
1 3

output:

24

result:

ok 1 number(s): "24"

Test #2:

score: 0
Accepted
time: 3ms
memory: 26228kb

input:

3
1 2
1 3
1 2
2 3

output:

22

result:

ok 1 number(s): "22"

Test #3:

score: -100
Wrong Answer
time: 3ms
memory: 31388kb

input:

500
30 198
198 333
198 17
333 430
333 44
17 99
17 19
430 160
430 162
44 154
44 253
99 466
99 397
19 301
19 101
160 416
160 446
162 375
162 174
154 256
154 170
253 67
253 248
466 462
466 216
397 104
397 306
301 460
301 464
101 226
101 50
416 137
416 456
446 443
446 465
375 92
375 266
174 209
174 84
2...

output:

48559018

result:

wrong answer 1st numbers differ - expected: '75020868', found: '48559018'