QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#88812 | #2564. Two Trees | s8194272 | TL | 2ms | 17696kb | C++14 | 5.0kb | 2023-03-17 16:04:05 | 2023-03-17 16:04:06 |
Judging History
answer
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<bitset>
#include<random>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define uint unsigned int
#define fi first
#define se second
#define max Max
#define min Min
#define abs Abs
#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
#define pb(x) push_back(x)
#define lowbit(x) ((x)&(-(x)))
#define fan(x) ((((x)-1)^1)+1)
#define mp(x,y) make_pair(x,y)
#define clr(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
#define SZ(x) ((int)(x.size()))
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{
int ans=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){ans=(ans<<1)+(ans<<3)+c-'0';c=getchar();}
return ans*f;
}
inline void write(uint x)
{
if(x/10) write(x/10);
putchar((char)(x%10)+'0');
}
template<typename T>inline T Abs(T a){return a>0?a:-a;};
template<typename T,typename TT>inline T Min(T a,TT b){return a<b?a:b;}
template<typename T,typename TT> inline T Max(T a,TT b){return a<b?b:a;}
const int N=2e5+5;
int n,vis[N],dep[N],a[N<<1],b[N],Cnt,St[20][N<<1],dfn[N],cnt;
uint ans;
struct Edge
{
int v,w,ne;
}e[2][N];
int head[2][N],tot[2];
inline void add(int p,int u,int v,int w=0)
{
e[p][++tot[p]]=(Edge){v,w,head[p][u]};
head[p][u]=tot[p];
}
int mn,ps,sz[N],all;
void dfs0(int u,int fa)
{
all++;
for(int i=head[0][u];i;i=e[0][i].ne)
{
int v=e[0][i].v;
if(v==fa||vis[v])
continue;
dfs0(v,u);
}
}
void dfs1(int u,int fa)
{
sz[u]=1;int tmp=0;
for(int i=head[0][u];i;i=e[0][i].ne)
{
int v=e[0][i].v;
if(v==fa||vis[v])
continue;
dfs1(v,u);sz[u]+=sz[v];
tmp=max(tmp,sz[v]);
}
tmp=max(tmp,all-sz[u]);
if(tmp<mn) mn=tmp,ps=u;
}
inline int findrt(int u)
{
all=0;mn=INF;ps=-1;
dfs0(u,0);dfs1(u,0);
return ps;
}
void dfs(int u,int fa)
{
dfn[u]=++cnt;
dep[u]=dep[fa]+1;
a[++Cnt]=u;b[u]=Cnt;
for(int i=head[1][u];i;i=e[1][i].ne)
{
int v=e[1][i].v;
if(v==fa) continue;
dfs(v,u);
a[++Cnt]=u;
}
}
inline int LCA(int x,int y)
{
x=b[x];y=b[y];
if(x>y) swap(x,y);
int k=__lg(y-x+1);
if(dep[St[k][x]]<dep[St[k][y-(1<<k)+1]])
return St[k][x];
return St[k][y-(1<<k)+1];
}
vector<int> hv;
int val[N],st[N],top;
inline void insert(int x)
{
int lst=st[top];top--;
while(top&&LCA(st[top],x)!=st[top])
{
add(1,st[top],lst,dep[lst]-dep[st[top]]);
lst=st[top];top--;
}
int lca=LCA(lst,x);
if(lca!=lst)
{
add(1,lca,lst,dep[lst]-dep[lca]);
hv.push_back(lca);
}
if(st[top]!=lca)
st[++top]=lca;
hv.push_back(x);
st[++top]=x;
}
uint f0[N],f1[N],f2[N],res;
void DP(int u,int fa)
{
if(val[u]!=-1)
{
f0[u]=1,f1[u]=val[u],f2[u]=val[u]*1u*val[u];
res+=val[u]*1u*val[u];
}
else f0[u]=0,f1[u]=0,f2[u]=0;
for(int i=head[1][u];i;i=e[1][i].ne)
{
int v=e[1][i].v;
if(v==fa) continue;
DP(v,u);
uint F0=f0[v],F1=f1[v]+f0[v]*e[1][i].w;
uint F2=f2[v]+2*f1[v]*e[1][i].w+f0[v]*e[1][i].w*e[1][i].w;
res+=f0[u]*F2+2*f1[u]*F1+f2[u]*F0;
f2[u]+=F2;f1[u]+=F1;f0[u]+=F0;
}
}
inline uint query(vector<int> nd)
{
st[++top]=1;hv.push_back(1);res=0;
for(auto i:nd) if(i!=1) insert(i);
for(int i=1;i<top;++i)
add(1,st[i],st[i+1],dep[st[i+1]]-dep[st[i]]);
DP(1,0);
for(auto i:hv)
head[1][i]=0,val[i]=-1;
tot[1]=0;nd.clear();hv.clear();top=0;
return res;
}
void dfs2(int u,int fa,int len)
{
val[u]=len;
for(int i=head[0][u];i;i=e[0][i].ne)
{
int v=e[0][i].v;
if(v==fa||vis[v]) continue;
dfs2(v,u,len+1);
}
}
struct node
{
int u,w;
bool operator < (const node &x)const
{
return dfn[w]>dfn[x.w];
}
};
int lim[N];
vector<int> solve(int u)
{
u=findrt(u);vis[u]=1;
vector<int> now;
vector<vector<int> > merg;
for(int i=head[0][u];i;i=e[0][i].ne)
{
int v=e[0][i].v;
if(vis[v]) continue;
vector<int> tmp=solve(v);
dfs2(v,u,1);ans-=query(tmp);
merg.push_back(tmp);
}
priority_queue<node> qu;
for(int i=0;i<SZ(merg);++i)
lim[i]=0,qu.push((node){i,merg[i][lim[i]++]});
int flg=0;
while(!qu.empty())
{
int U=qu.top().u;
int w=qu.top().w;
if(dfn[u]<dfn[w])
now.push_back(u),flg=1;
now.push_back(w);qu.pop();
if(lim[U]<SZ(merg[U]))
qu.push((node){U,merg[U][lim[U]++]});
}
if(!flg) now.push_back(u);
vis[u]=0;
dfs2(u,0,0);
ans+=query(now);
return now;
}
signed main()
{
n=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
add(0,u,v);add(0,v,u);
}
for(int i=1;i<n;++i)
{
int u=read(),v=read();
add(1,u,v);add(1,v,u);
}
dfs(1,0);
for(int i=1;i<=Cnt;++i)
St[0][i]=a[i];
for(int j=1;j<20;++j)
for(int i=1;i+(1<<j)-1<=Cnt;++i)
if(dep[St[j-1][i]]<dep[St[j-1][i+(1<<(j-1))]])
St[j][i]=St[j-1][i];
else St[j][i]=St[j-1][i+(1<<(j-1))];
for(int i=1;i<=n;++i)
head[1][i]=0;tot[1]=0;
memset(val,-1,sizeof(val));
solve(1);
write(ans);
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 2ms
memory: 17696kb
input:
3 1 2 1 3 1 2 1 3
output:
24
result:
ok 1 number(s): "24"
Test #2:
score: 0
Accepted
time: 2ms
memory: 15620kb
input:
3 1 2 1 3 1 2 2 3
output:
22
result:
ok 1 number(s): "22"
Test #3:
score: -100
Time Limit Exceeded
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...