提交时间:2024-07-20 11:24:10

运行 ID: 30600

#include<iostream> #include<algorithm> #include<cstring> #include<ctime> #define timeMS (clock()*1000/CLOCKS_PER_SEC) int clk; using namespace std; #define int long long inline int read(){ int i=getchar(),r=0; while(i<'0'||i>'9')i=getchar(); while(i>='0'&&i<='9')r=(r<<1)+(r<<3)+(i^48),i=getchar(); return r; } const int N=1<<17,P=1000000007; inline int fpow(int a,int b=P-2){ int c=1; for(;b;b>>=1,a=a*a%P)if(b&1)c=c*a%P; return c; } int len[N<<1]; class bst{ public: int sum[N<<1],laz[N<<1];//sum: 子树内的 laz 之和 bst(){memset(sum,0,sizeof(sum));memset(laz,0,sizeof(laz));} inline int get_sum(int l,int r){ int res=0; int lenl=0,lenr=0; for(l=N+l-1,r=N+r+1;(l>>1)!=(r>>1);l>>=1,r>>=1){ if(!(l&1))res=(res+sum[l^1])%P,lenl+=len[l]; if(r&1)res=(res+sum[r^1])%P,lenr+=len[r]; res=(res+laz[l>>1]*lenl+laz[r>>1]*lenr)%P; } for(int x=(l>>1);x;x>>=1)res=(res+laz[x]*(lenl+lenr))%P; return res; } inline void add(int l,int r,int k){ int suml=0,sumr=0; for(l=N+l-1,r=N+r+1;(l>>1)!=(r>>1);l>>=1,r>>=1){ if(!(l&1)){ laz[l^1]=(laz[l^1]+k)%P; sum[l^1]=(sum[l^1]+k*len[l])%P; suml=(suml+k*len[l])%P; } if(r&1){ laz[r^1]=(laz[r^1]+k)%P; sum[r^1]=(sum[r^1]+k*len[r])%P; sumr=(sumr+k*len[r])%P; } sum[l>>1]=(sum[l>>1]+suml)%P; sum[r>>1]=(sum[r>>1]+sumr)%P; } for(int x=(l>>1);x;x>>=1)sum[x]=(sum[x]+(suml+sumr))%P; } }ds1,ds2; int n,head[N],to[N<<1],nex[N<<1],l[N],r[N],ilen[N],prd=1; int siz[N]; bool vis[N]; int ans=0; void init(){ cin>>n; for(int i=1;i<=n;i++){ l[i]=read(); r[i]=read(); prd=prd*(r[i]-l[i]+1)%P; ilen[i]=fpow(r[i]-l[i]+1); } for(int i=1;i<n;i++){ int u=read(),v=read(); to[i<<1]=v; nex[i<<1]=head[u]; head[u]=i<<1; to[i<<1|1]=u; nex[i<<1|1]=head[v]; head[v]=i<<1|1; } for(int i=0;i<N;i++)len[i+N]=1; for(int t=N>>1;t>=1;t>>=1){ for(int j=0;j<t;j++)len[j+t]=len[(j+t)<<1]<<1; } } int get_siz(int nd,int fa){ siz[nd]=1; for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa)siz[nd]+=get_siz(to[i],nd); return siz[nd]; } int barycenter(int nd,int clk,int fa){ int mx=clk-siz[nd]; for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa)mx=max(mx,siz[to[i]]); if(mx*2<=clk)return nd; for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa){ int x=barycenter(to[i],clk,nd); if(x)return x; } return 0; } void calc(int nd,int dis,int fa){ ans=(ans+(ds1.get_sum(l[nd],r[nd])*dis+ds2.get_sum(l[nd],r[nd]))%P*ilen[nd])%P; for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa)calc(to[i],dis+1,nd); } void add(int nd,int dis,int fa){ ds1.add(l[nd],r[nd],ilen[nd]); ds2.add(l[nd],r[nd],dis*ilen[nd]%P); for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa)add(to[i],dis+1,nd); } void clear(int nd,int dis,int fa){ ds1.add(l[nd],r[nd],-ilen[nd]); ds2.add(l[nd],r[nd],-dis*ilen[nd]%P); for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]&&to[i]!=fa)clear(to[i],dis+1,nd); } void solve(int nd){ nd=barycenter(nd,get_siz(nd,0),0); vis[nd]=true; ds1.add(l[nd],r[nd],ilen[nd]); for(int i=head[nd];i;i=nex[i])if(!vis[to[i]]){ calc(to[i],1,nd); add(to[i],1,nd); } clear(nd,0,0); for(int i=head[nd];i;i=nex[i])if(!vis[to[i]])solve(to[i]); } signed main(){ // freopen("route.in","r",stdin); // freopen("ex_route6.in","r",stdin); // freopen("route.out","w",stdout); init(); solve(1); cout<<(ans+P)%P*prd%P; // cerr<<timeMS<<' '<<clk; return 0; }