提交时间:2024-07-19 12:32:58
运行 ID: 30376
#include<bits/stdc++.h> using namespace std; #define int long long #define pb push_back #define inx int I=h[u],v=edge[I].v;I;I=edge[I].nx,v=edge[I].v inline int read(){int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x*f;} const int MAXN=300010,Mod=1000000007; struct Edge{int v,nx;}edge[MAXN<<1];int h[MAXN],CNT;void add_side(int u,int v){edge[++CNT]={v,h[u]};h[u]=CNT;edge[++CNT]={u,h[v]};h[v]=CNT;} int n,a[MAXN],b[MAXN],sm,ny[MAXN]; int dfs(int u,int lst,int id,int t){ int res=sm*ny[b[id]-a[id]+1]%Mod*ny[b[u]-a[u]+1]%Mod*t%Mod*max(0ll,min(b[u],b[id])-max(a[u],a[id])+1)%Mod; // cout<<u<<" "<<lst<<" "<<" "<<sm*ny[b[id]-a[id]+1]%Mod*ny[b[u]-a[u]+1]%Mod<<" "<<max(0ll,min(b[u],b[id])-max(a[u],a[id])+1)<<" "<<t<<endl; for(inx)if(v!=lst){ res=(res+dfs(v,u,id,t+1))%Mod; } return res; } int Pow(int x,int y){int rt=1;while(y){if(y&1)rt=rt*x%Mod;x=x*x%Mod,y>>=1;}return rt;} int vis[MAXN],zx,sz,tp; int getsz(int u,int lst){ if(vis[u])return 0; int res=1; for(inx)if(v!=lst){ res+=getsz(v,u); } return res; } int getzx(int u,int lst){ if(vis[u])return 0; int res=1,mx=0; for(inx)if(v!=lst){ int tmp=getzx(v,u); res+=tmp;mx=max(mx,tmp); } mx=max(mx,n-res); if(mx<tp)tp=mx,zx=u; return res; } int num[MAXN],sum[MAXN],ans; void count(int u,int lst,int d){ if(vis[u])return; ans+=(num[a[u]]*d+sum[a[u]])%Mod; for(inx)if(v!=lst){ count(v,u,d+1); } } void add(int u,int lst,int d,int lf){ if(vis[u])return; num[a[u]]+=lf;sum[a[u]]+=d*lf; for(inx)if(v!=lst){ add(v,u,d+1,lf); } } void getans(int u){ num[a[u]]++; for(inx)if(!vis[v]){ count(v,u,1); add(v,u,1,1); } for(inx)if(!vis[v]){ add(v,u,1,-1); } num[a[u]]--; } void dfz(int u,int lst){ sz=getsz(u,lst);tp=n; int tmp=getzx(u,lst); getans(zx); vis[zx]=1; u=zx; for(inx)if(!vis[v]){ dfz(v,u); } } void slv(){ n=read(); for(int i=1;i<MAXN-5;i++)ny[i]=Pow(i,Mod-2); sm=1; for(int i=1;i<=n;i++)a[i]=read(),b[i]=read(),sm=sm*(b[i]-a[i]+1)%Mod; for(int i=1;i<n;i++){ int u=read(),v=read(); add_side(u,v); } if(n<=2000){ int ans=0; for(int i=1;i<=n;i++){ // cout<<i<<":"<<endl; int tmp; ans+=tmp=dfs(i,i,i,0); ans%=Mod; // cout<<tmp<<endl; } printf("%lld",ans*Pow(2,Mod-2)%Mod); } else{ dfz(1,1);//cout<<ans<<endl; printf("%lld",ans); } } signed main(){ slv(); return 0; }