QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#295779 | #4901. Speike & Tom | ucup-team1004 | 10 | 28ms | 21964kb | C++14 | 8.4kb | 2023-12-31 22:50:22 | 2023-12-31 22:50:22 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define all(a) (a).begin(),(a).end()
#ifdef DEBUG
template<class T>
ostream& operator << (ostream &out,vector<T> a){
out<<'[';
for(T x:a)out<<x<<',';
return out<<']';
}
template<class T>
vector<T> ary(T *a,int l,int r){
return vector<T>{a+l,a+1+r};
}
template<class T>
void debug(T x){
cerr<<x<<endl;
}
template<class T,class...S>
void debug(T x,S...y){
cerr<<x<<' ',debug(y...);
}
#else
#define debug(...) void()
#endif
const int N=1e5+10;
int n,m;
vector<int>to[N],tr[N];
namespace Tree{
int dep[N],fa[N],siz[N],top[N],son[N];
void dfs1(int u){
dep[u]=dep[fa[u]]+1;
for(int v:to[u])if(v^fa[u]){
fa[v]=u,dfs1(v);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t;
if(son[u])dfs2(son[u],t);
for(int v:to[u])if(v^fa[u]&&v^son[u])dfs2(v,v);
}
int LCA(int u,int v){
for(;top[u]^top[v];u=fa[top[u]]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
}
return dep[u]<dep[v]?u:v;
}
int sum[N];
void link(int u,int v){
if(dep[u]<dep[v])swap(u,v);
if(fa[u]==v)return;
if(fa[fa[u]]==v||fa[u]==fa[v]){
tr[u].push_back(v),tr[v].push_back(u);
}else{
int t=LCA(u,v);
sum[u]++,sum[t]--;
sum[v]++,sum[fa[t]]--;
}
}
void init(){
dfs1(1),dfs2(1,1);
}
void push1(int u=1){
for(int v:to[u])if(v^fa[u]){
push1(v);
sum[u]+=sum[v];
}
}
int tot[N];
void push2(int u=1){
tot[u]=!!sum[u];
for(int v:to[u])if(v^fa[u]){
push2(v);
tot[u]+=tot[v];
}
}
int count(int u,int v){
if(fa[u]==v)return tot[1]-tot[u];
else if(fa[v]==u)return tot[v];
else return 0;
}
bool count(int u){
return !!sum[u];
}
}
using Tree::count;
bool chk(int u,int v){
return find(all(tr[u]),v)!=tr[u].end();
}
ll ans;
int rt,siz[N],mx[N],vis[N],dep[N],dis[N];
void dfs1(int u,int fa=0){
siz[u]=1,mx[u]=0;
for(int v:to[u])if(v^fa&&!vis[v]){
dfs1(v,u);
siz[u]+=siz[v];
mx[u]=max(mx[u],siz[v]);
}
}
void dfs2(int s,int u,int fa=0){
mx[u]=max(mx[u],s-siz[u]);
for(int v:to[u])if(v^fa&&!vis[v]){
dfs2(s,v,u);
}
if(mx[u]<mx[rt])rt=u;
}
void dfs3(int u,int fa=0){
dep[u]=dep[fa]+1;
for(int v:to[u])if(v^fa){
if(!vis[v])dfs3(v,u);
else dep[v]=dep[u]+1;
}
}
namespace Jump{
const int K=__lg(N)+1;
int tag[N],anc[K][N];
vector<int>pos;
void dfs(int u,int fa=0){
pos.push_back(u);
anc[0][u]=fa;
for(int v:tr[u])if(dep[v]==dep[u]-2)anc[0][u]=v;
tag[u]=tag[anc[0][u]];
if(fa!=rt&&anc[0][u]==rt)tag[u]=1;
for(int v:to[u])if(v^fa){
if(!vis[v])dfs(v,u);
else{
pos.push_back(v),anc[0][v]=u;
for(int w:tr[v])if(w==fa)anc[0][v]=w;
tag[v]=tag[anc[0][v]];
if(u!=rt&&anc[0][v]==rt)tag[v]=1;
}
}
}
void init(int u){
pos.clear(),dfs(u);
for(int i=1;(1<<i)<=n;i++){
for(int u:pos)anc[i][u]=anc[i-1][anc[i-1][u]];
}
}
int jump(int u,int t){
int ans=0;
for(int i=__lg(dep[u]-dep[t]);~i;i--){
if(dep[anc[i][u]]>=dep[t])u=anc[i][u],ans+=1<<i;
}
return ans+(dep[u]>dep[t]);
}
}
using Jump::jump;
void dfs4(int s,int u,int fa=0){
dis[u]=jump(u,s),siz[u]=1;
for(int v:to[u])if(v^fa){
if(!vis[v]){
dfs4(s,v,u);
siz[u]+=siz[v];
}else{
dis[v]=jump(v,s);
}
}
}
struct BIT1{
int c[N];
vector<pair<int,int>>upd;
void add(int x,int y){
upd.push_back({x,-y});
for(;x;x^=x&-x)c[x]+=y;
}
int get(int x,int y=0){
for(;x<=n;x+=x&-x)y+=c[x];
return y;
}
int count(){
return upd.size();
}
void clr(int lim=0){
for(int x,y;upd.size()>lim;upd.pop_back()){
for(tie(x,y)=upd.back();x;x^=x&-x)c[x]+=y;
}
}
};
struct BIT2{
int c[N];
vector<pair<int,int>>upd;
void add(int x,int y){
upd.push_back({x,-y});
for(;x<=n;x+=x&-x)c[x]+=y;
}
int get(int x,int y=0){
for(;x;x^=x&-x)y+=c[x];
return y;
}
int count(){
return upd.size();
}
void clr(int lim=0){
for(int x,y;upd.size()>lim;upd.pop_back()){
for(tie(x,y)=upd.back();x<=n;x+=x&-x)c[x]+=y;
}
}
};
namespace Solve1{
BIT1 A;
void query(int u,int fa,int t=0,int p=0){
if(count(fa,u))t=u,p=0;
if(t){
// debug(u,t,p,A.get(max(0,jump(u,t)-dep[t]+p+1)+1));
ans+=A.get(max(0,jump(u,t)-dep[t]+p+1)+1);
}
for(int v:to[u])if(v^fa&&!vis[v]){
int tt=t,pp=p;
for(int w:tr[v]){
if(dep[v]==dep[w]&&count(u,w))tt=v,pp=1;
}
query(v,u,tt,pp);
}
}
void insert(int w,int u,int fa){
A.add(dep[u]+1,w);
for(int v:to[u])if(v^fa&&!vis[v]){
insert(w,v,u);
}
}
void solve(int u){
A.add(dep[u]+1,1);
for(int v:to[u])if(!vis[v])insert(1,v,u);
for(int v:to[u])if(!vis[v]){
insert(-1,v,u),query(v,u),insert(1,v,u);
}
A.clr();
}
}
namespace Solve2{
BIT2 A[2];
void update(int t,int w,int u,int fa=0){
A[t].add(dis[u]+1,w);
for(int v:to[u])if(v^fa&&!vis[v]){
update(t,w,v,u);
}
}
void query(int u,int fa=0,int t=0,int d=0){
if(t){
// debug(u,t,d,dis[t],ans);
ans+=A[0].get(max(0,d-dis[t]-1+1));
// debug(ans,ary(Jump::tag,1,n),Jump::anc[0][5]);
ans+=A[1].get(max(0,d-dis[t]-Jump::tag[t]+1));
// debug(ans);
}
int fi=0,se=0;
for(int v:to[u])if(v^fa){
if(count(u,v))(fi?se:fi)=v;
}
for(int v:to[u])if(v^fa&&!vis[v]){
if(t)query(v,u,t,d+1);
else if(fi&&v!=fi)query(v,u,fi,2);
else if(se&&v!=se)query(v,u,se,2);
else if(count(v,u))query(v,u,u,1);
else query(v,u);
}
}
int tag[N];
void solve(int u){
if(!count(u))A[0].add(dis[u]+1,1);
for(int v:to[u])if(!vis[v])tag[v]=u;
for(int v:to[u])if(!vis[v]&&!count(u,v)){
update(0,1,v,u);
}
for(int v:to[u])if(!vis[v]&&!count(v,u)){
int las=A[0].count();
for(int w:tr[v])if(tag[w]==u){
update(1,1,w,u),update(0,-1,w,u);
}
// debug(rt,v,ary(Tree::sum,1,n));
query(v,u);
A[0].clr(las),A[1].clr();
}
A[0].clr();
}
}
namespace Solve3{
BIT1 A[2];
void update(int t,int w,int u,int fa=0){
A[t].add(dep[u]+1,w);
for(int v:to[u])if(v^fa&&!vis[v]){
update(t,w,v,u);
}
}
void query(int o,int t,int p,int u,int fa=0){
// debug(u,t,jump(u,t));
ans+=A[o].get(jump(u,t)+p+1);
for(int v:to[u])if(v^fa&&!vis[v]){
query(o,t,p,v,u);
}
}
int tag[N];
vector<int>o[N];
void solve(int u){
A[0].add(dep[u]+1,1),A[1].add(dep[u]+1,1);
int cur=0;
for(int v:to[u])if(!vis[v]){
tag[v]=u;
if(!count(u,v))update(1,1,v,u);
else if(cur)cur=-1;
else cur=v;
}
if(count(u)){
for(int v:to[u])if(!vis[v])update(0,1,v,u);
}else{
for(int v:to[u])if(!vis[v]&&v^cur)update(0,1,v,u);
}
for(int v:to[u])if(!vis[v]&&!count(u,v)){
int las=A[0].count(),pos=A[1].count();
update(0,-1,v,u),update(1,-1,v,u);
int fi=0,se=0;
for(int w:tr[v]){
if(count(u,w))(fi?se:fi)=w;
}
// debug(v,fi,se,tr[v]);
if(fi&&se){
query(0,v,1,v);
}else if(fi){
if(tag[fi]==u){
o[fi].push_back(v);
}else query(0,v,1,v);
}else{
if(count(u))query(0,u,1,v);
else if(!cur)query(0,u,1,v);
else if(cur>0)query(1,u,1,v);
else query(0,u,1,v);
}
// debug(v,ans);
A[0].clr(las),A[1].clr(pos);
}
A[1].clr();
for(int v:to[u])if(!vis[v]){
if(o[v].empty())continue;
int las=A[0].count();
if(v^cur||count(u))update(0,-1,v,u);
update(1,1,v,u);
for(int w:o[v]){
int las=A[0].count();
update(0,-1,w,u);
// debug("st",v,w,ans);
query(0,w,1,w);
// debug("mid",v,w,ans);
if(v^cur||count(u))query(1,u,1,w);
// debug("ed",v,w,ans);
A[0].clr(las);
}
A[0].clr(las),A[1].clr();
o[v].clear();
}
for(int v:to[u])if(!vis[v]){
if(count(v,u)){
// debug(u,v,siz[v]);
ans+=siz[v];
}
}
A[0].clr(),A[1].clr();
}
}
void solve(int u){
rt=0,dfs1(u),dfs2(siz[u],u),vis[u=rt]=1;
dfs3(u),Jump::init(u),dfs4(u,u);
Solve1::solve(u);
Solve2::solve(u);
Solve3::solve(u);
// debug("root",u,ans);
// if(u==2)exit(0);
for(int v:to[u])if(!vis[v])solve(v);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
to[u].push_back(v),to[v].push_back(u);
}
Tree::init();
for(int u,v;m--;){
scanf("%d%d",&u,&v);
Tree::link(u,v);
}
for(int i=1;i<=n;i++){
sort(tr[i].begin(),tr[i].end());
}
Tree::push1();
Tree::push2();
// debug("sum",ary(Tree::sum,1,n));
if(!Tree::tot[1])puts("0"),exit(0);
mx[0]=n+1,dep[0]=-1,solve(1);
cout<<ans<<endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 10
Accepted
Test #1:
score: 10
Accepted
time: 0ms
memory: 19052kb
input:
20 3 1 2 1 3 3 4 4 5 1 6 6 7 1 8 5 9 8 10 5 11 7 12 11 13 12 14 11 15 4 16 7 17 2 18 1 19 3 20 8 20 12 4 10 1
output:
307
result:
ok 1 number(s): "307"
Test #2:
score: 0
Accepted
time: 0ms
memory: 21272kb
input:
20 4 1 2 2 3 1 4 3 5 4 6 3 7 4 8 3 9 2 10 8 11 8 12 7 13 8 14 14 15 4 16 1 17 4 18 6 19 19 20 9 13 14 2 14 13 15 6
output:
343
result:
ok 1 number(s): "343"
Test #3:
score: 0
Accepted
time: 0ms
memory: 19032kb
input:
19 4 1 2 1 3 1 4 4 5 4 6 3 7 7 8 6 9 4 10 2 11 6 12 7 13 1 14 13 15 6 16 12 17 3 18 3 19 8 12 4 6 18 5 11 9
output:
314
result:
ok 1 number(s): "314"
Test #4:
score: 0
Accepted
time: 0ms
memory: 21068kb
input:
20 3 1 2 2 3 3 4 4 5 1 6 2 7 1 8 3 9 9 10 5 11 8 12 10 13 12 14 8 15 9 16 11 17 5 18 17 19 19 20 9 19 10 15 18 15
output:
358
result:
ok 1 number(s): "358"
Test #5:
score: 0
Accepted
time: 3ms
memory: 19024kb
input:
20 6 1 2 1 3 3 4 4 5 1 6 6 7 5 8 4 9 7 10 6 11 10 12 6 13 10 14 1 15 15 16 8 17 17 18 15 19 18 20 17 2 16 3 10 1 8 7 13 5 19 7
output:
361
result:
ok 1 number(s): "361"
Test #6:
score: 0
Accepted
time: 0ms
memory: 18988kb
input:
20 8 1 2 2 3 1 4 1 5 1 6 4 7 2 8 4 9 2 10 1 11 11 12 2 13 10 14 1 15 6 16 16 17 11 18 10 19 3 20 2 6 6 7 1 18 18 13 1 20 3 12 8 4 7 1
output:
324
result:
ok 1 number(s): "324"
Subtask #2:
score: 0
Runtime Error
Dependency #1:
100%
Accepted
Test #7:
score: 0
Runtime Error
input:
300 26 1 2 1 3 2 4 4 5 3 6 6 7 5 8 2 9 1 10 10 11 6 12 8 13 6 14 10 15 6 16 4 17 9 18 10 19 5 20 18 21 6 22 10 23 18 24 1 25 19 26 17 27 8 28 10 29 25 30 16 31 27 32 13 33 4 34 5 35 12 36 9 37 15 38 32 39 29 40 11 41 5 42 28 43 1 44 25 45 27 46 3 47 34 48 27 49 9 50 39 51 20 52 48 53 10 54 35 55 23 ...
output:
result:
Subtask #3:
score: 0
Skipped
Dependency #2:
0%
Subtask #4:
score: 0
Skipped
Dependency #3:
0%
Subtask #5:
score: 0
Runtime Error
Test #29:
score: 10
Accepted
time: 28ms
memory: 21100kb
input:
98765 1 2 1 3 1 4 2 5 2 6 5 7 4 8 6 9 7 10 7 11 6 12 1 13 11 14 13 15 7 16 6 17 14 18 4 19 13 20 14 21 11 22 21 23 1 24 13 25 7 26 16 27 8 28 21 29 20 30 10 31 12 32 10 33 7 34 31 35 29 36 29 37 30 38 34 39 38 40 14 41 40 42 26 43 33 44 1 45 44 46 25 47 14 48 2 49 30 50 26 51 46 52 34 53 32 54 31 55...
output:
0
result:
ok 1 number(s): "0"
Test #30:
score: 0
Accepted
time: 27ms
memory: 21964kb
input:
99824 1 2 1 3 1 4 1 5 1 6 2 7 2 8 1 9 3 10 9 11 4 12 6 13 6 14 2 15 3 16 9 17 13 18 15 19 4 20 13 21 12 22 15 23 5 24 16 25 17 26 9 27 26 28 18 29 8 30 23 31 5 32 31 33 28 34 5 35 11 36 20 37 6 38 36 39 35 40 4 41 11 42 10 43 12 44 28 45 15 46 38 47 9 48 36 49 16 50 45 51 49 52 44 53 6 54 12 55 5 56...
output:
0
result:
ok 1 number(s): "0"
Test #31:
score: -10
Runtime Error
input:
67765 1 2 1 3 2 4 1 5 2 6 2 7 3 8 4 9 3 10 5 11 6 12 4 13 7 14 13 15 11 16 11 17 3 18 8 19 2 20 13 21 19 22 7 23 14 24 7 25 6 26 21 27 1 28 1 29 2 30 16 31 9 32 31 33 26 34 1 35 21 36 10 37 32 38 16 39 38 40 10 41 20 42 23 43 8 44 10 45 14 46 42 47 12 48 17 49 45 50 28 51 42 52 49 53 44 54 9 55 8 56...
output:
result:
Subtask #6:
score: 0
Skipped
Dependency #1:
100%
Accepted
Dependency #2:
0%