1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; using ll=long long; const int N=1000010,FSIZE=1<<26; int n,m,dp[N],mx[N],s[N][21],all[N],num[N],l[N],r[N],up[N],to[N]; bool is[N],tag[N],can[N]; ll ans; vector<pair<int,int>> p[N]; vector<int> t[N],rm[N]; char BuF[FSIZE],*InF=BuF; template<typename T>void read(T &x){ for(;*InF<33;++InF); for(x=0;*InF>32;x=x*10+(*InF++^48)); } int lca(int x,int y){ if(dp[x]<dp[y]) swap(x,y); int l=x,r=y; for(int i=mx[l];dp[l]>dp[r];--i) if(dp[s[l][i]]>=dp[r]) l=s[l][i]; if(l==r) return(l); for(int i=mx[l];~i;--i) if(s[l][i]!=s[r][i]){ l=s[l][i]; r=s[r][i]; } return(s[l][0]); } void dfs1(int x,int fa=0){ dp[x]=dp[s[x][0]=fa]+1; for(int &i=mx[x];(s[x][i+1]=s[s[x][i]][i]);++i); for(int i:t[x]) if(i!=fa) dfs1(i,x); } void down(int x,int fa){ tag[x]=1; for(int i:t[x]) if(i!=fa&&!tag[i]) down(i,x); } void dfs2(int x,int fa=0){ for(int i:t[x]) if(i!=fa) dfs2(i,x); for(auto i:p[x]) if(!tag[i.first]&&!tag[i.second]){ is[num[x]=x]=1; return(down(x,fa)); } } void dfs3(int x,int fa=0){ all[x]=all[fa]+is[x]; num[x]^=num[fa]; for(int i:t[x]) if(i!=fa) dfs3(i,x); } void push(int cnt,int x,int fa){ if(is[x]) return; for(int i:t[x]) if(i!=fa){ push(cnt,i,x); to[x]+=to[i]; } if(to[x]<cnt) can[x]=1; } void dfs4(int x,int fa=0){ if(is[x]){ int cnt=0; for(int i:rm[x]) if(up[i]==x||can[up[i]]){ ++to[l[i]]; ++to[r[i]]; ++cnt; } is[x]=0; push(cnt,x,fa); for(int i:rm[x]) if(up[i]==x||can[up[i]]) to[l[i]]=to[r[i]]=0; } for(int i:t[x]) if(i!=fa) dfs4(i,x); } int count(int x,int fa=0){ can[x]=0; int re=1; for(int i:t[x]) if(i!=fa&&can[i]) re+=count(i,x); return(re); } int main(){ fread(BuF,1,FSIZE,stdin); read(n);read(m); for(int i=1,x,y;i<n;++i){ read(x);read(y); t[x].push_back(y); t[y].push_back(x); } dfs1(1); for(int i=1;i<=m;++i){ read(l[i]);read(r[i]); p[up[i]=lca(l[i],r[i])].emplace_back(l[i],r[i]); } dfs2(1); dfs3(1); for(int i=1;i<=m;++i) if(all[l[i]]+all[r[i]]-all[up[i]]-all[s[up[i]][0]]==1) rm[num[l[i]]^num[r[i]]^num[up[i]]^num[s[up[i]][0]]].push_back(i); if(!is[1]) push(1,1,0); dfs4(1); for(int i=1;i<=n;++i) if(can[i]){ int x=count(i); ans+=(ll)x*x; } printf("%lld\n",ans); return(0); }
|