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 }

 

posted @ 2018-03-02 09:50  大奕哥&VANE  阅读(540)  评论(1编辑  收藏  举报