BZOJ3772精神污染
参见http://blog.csdn.net/popoqqq/article/details/43122821
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10; 5 ll ans;int n,m,idx,cnt,head[N],tmp,rt[N],f[N][20],d[N],in[N],out[N]; 6 vector<int>p[N]; 7 struct tree 8 { 9 int w,l,r; 10 }t[3500005]; 11 struct node 12 { 13 int x,y; 14 }q[N]; 15 bool cmp(node a,node b) 16 { 17 return a.x==b.x?a.y<b.y:a.x<b.x; 18 } 19 struct edge 20 { 21 int to,nex; 22 }e[N<<1]; 23 void add(int x,int y) 24 { 25 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt; 26 } 27 void change(int &x,int y,int l,int r,int p,int w) 28 { 29 if(x==y||!x)x=++tmp,t[x]=t[y]; 30 if(l==r){ 31 t[x].w+=w;return; 32 } 33 int mid=l+r>>1; 34 if(p<=mid)change(t[x].l,t[y].l,l,mid,p,w); 35 else change(t[x].r,t[y].r,mid+1,r,p,w); 36 t[x].w=t[t[x].l].w+t[t[x].r].w; 37 } 38 void dfs(int x) 39 { 40 in[x]=++idx; 41 for(int i=1;i<20;++i)f[x][i]=f[f[x][i-1]][i-1]; 42 for(int i=head[x];i;i=e[i].nex) 43 { 44 int y=e[i].to; 45 if(y==f[x][0])continue; 46 d[y]=d[x]+1;f[y][0]=x; 47 dfs(y); 48 } 49 out[x]=++idx; 50 return; 51 } 52 void dfs2(int x) 53 { 54 for(int i=0;i<p[x].size();++i) 55 { 56 change(rt[x],rt[f[x][0]],1,2*n,in[p[x][i]],1); 57 change(rt[x],rt[f[x][0]],1,2*n,out[p[x][i]],-1); 58 } 59 if(!p[x].size())rt[x]=rt[f[x][0]]; 60 for(int i=head[x];i;i=e[i].nex) 61 { 62 int y=e[i].to; 63 if(y==f[x][0])continue; 64 dfs2(y); 65 } 66 } 67 int query(int rt1,int rt2,int rt3,int rt4,int l,int r,int L,int R) 68 { 69 if(l==L&&r==R)return t[rt1].w+t[rt2].w-t[rt3].w-t[rt4].w;//线段树动态开点 70 int mid=l+r>>1; 71 if(R<=mid)return query(t[rt1].l,t[rt2].l,t[rt3].l,t[rt4].l,l,mid,L,R); 72 else if(L>mid)return query(t[rt1].r,t[rt2].r,t[rt3].r,t[rt4].r,mid+1,r,L,R); 73 else return query(t[rt1].l,t[rt2].l,t[rt3].l,t[rt4].l,l,mid,L,mid)+query(t[rt1].r,t[rt2].r,t[rt3].r,t[rt4].r,mid+1,r,mid+1,R); 74 } 75 int lca(int x,int y) 76 { 77 if(d[x]<d[y])swap(x,y); 78 int tt=d[x]-d[y]; 79 for(int i=0;i<20;++i) 80 if(tt&(1<<i))x=f[x][i]; 81 for(int i=19;i>=0;--i) 82 if(f[x][i]!=f[y][i]) 83 { 84 x=f[x][i];y=f[y][i]; 85 } 86 return x==y?x:f[x][0]; 87 } 88 ll gcd(ll a,ll b) 89 { 90 return b==0?a:gcd(b,a%b); 91 } 92 int main() 93 { 94 scanf("%d%d",&n,&m); 95 int x,y,z; 96 for(int i=1;i<n;++i) 97 { 98 scanf("%d%d",&x,&y); 99 add(x,y);add(y,x); 100 } 101 for(int i=1;i<=m;++i) 102 { 103 scanf("%d%d",&q[i].x,&q[i].y); 104 if(q[i].x>q[i].y)swap(q[i].x,q[i].y); 105 p[q[i].x].push_back(q[i].y); 106 } 107 dfs(1);dfs2(1); 108 for(int i=1;i<=m;++i) 109 { 110 x=q[i].x,y=q[i].y,z=lca(x,y); 111 ans+=query(rt[x],rt[y],rt[z],rt[f[z][0]],1,2*n,in[z],in[x]); 112 ans+=query(rt[x],rt[y],rt[z],rt[f[z][0]],1,2*n,in[z],in[y]); 113 ans-=query(rt[x],rt[y],rt[z],rt[f[z][0]],1,2*n,in[z],in[z]); 114 ans--; 115 } 116 sort(q+1,q+1+m,cmp); 117 for(int i=1,j=i+1;i<=m;i=j,j=i+1) 118 { 119 while(j<=m&&q[i].x==q[j].x&&q[i].y==q[j].y)++j; 120 ans-=1ll*(j-i)*(j-i-1)/2; 121 } 122 ll b=1ll*m*(m-1)/2,Gcd=gcd(ans,b); 123 printf("%lld/%lld\n",ans/Gcd,b/Gcd); 124 return 0; 125 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。