题解:P8290 [省选联考 2022] 填树
lupengheyyds · · 题解
首先不难想到一个
首先枚举最小值
bool Inc(int l,int r){return l<=mn&&mn<=r;}
int Inter(int l,int r){return max(0ll,min(r,mn+K)-max(l,mn)+1);}
int InterSum(int l,int r){
l=max(l,mn),r=min(r,mn+K);
if(l>r)return 0;
return (l+r)*(r-l+1)/2%MOD;
}
void DP(int x,int fa){
f[x][1]=Inc(l[x],r[x]);
g[x][1]=Inc(l[x],r[x])*mn;
f[x][0]=Inter(l[x],r[x])-f[x][1];
g[x][0]=InterSum(l[x],r[x])-g[x][1];
int v1=f[x][1],v0=f[x][0],g1=g[x][1],g0=g[x][0];
(ans1+=f[x][1])%=MOD;
(ans2+=g[x][1])%=MOD;
for(int y:ed[x]){
if(y==fa)continue;
DP(y,x);
(ans1+=f[x][1]*f[y][0]+f[x][1]*f[y][1]+f[x][0]*f[y][1])%=MOD;
(ans2+=g[x][1]*f[y][0]+g[x][1]*f[y][1]+g[x][0]*f[y][1]+
f[x][1]*g[y][0]+f[x][1]*g[y][1]+f[x][0]*g[y][1])%=MOD;
(g[x][1]+=v1*g[y][0]+v1*g[y][1]+v0*g[y][1]+
g1*f[y][0]+g1*f[y][1]+g0*f[y][1])%=MOD;
(g[x][0]+=v0*g[y][0]+g0*f[y][0])%=MOD;
(f[x][1]+=v1*f[y][0]+v1*f[y][1]+v0*f[y][1])%=MOD;
(f[x][0]+=v0*f[y][0])%=MOD;
}
return;
}
虽然这样会做
将
最终复杂度
完整代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int NN=805,MOD=1e9+7;
int n,K;
int f[NN][2],l[NN],r[NN],mn,ans1,ans2,mxr,fans,g[NN][2];
vector<int> ed[NN];
bool Inc(int l,int r){return l<=mn&&mn<=r;}
int Inter(int l,int r){return max(0ll,min(r,mn+K)-max(l,mn)+1);}
int InterSum(int l,int r){
l=max(l,mn),r=min(r,mn+K);
if(l>r)return 0;
return (l+r)*(r-l+1)/2%MOD;
}
int QP(int a,int b){
int c=1;
for(;b;b>>=1){
if(b&1)c=1ll*c*a%MOD;
a=1ll*a*a%MOD;
}
return c;
}
void DP(int x,int fa){
f[x][1]=Inc(l[x],r[x]);
g[x][1]=Inc(l[x],r[x])*mn;
f[x][0]=Inter(l[x],r[x])-f[x][1];
g[x][0]=InterSum(l[x],r[x])-g[x][1];
int v1=f[x][1],v0=f[x][0],g1=g[x][1],g0=g[x][0];
(ans1+=f[x][1])%=MOD;
(ans2+=g[x][1])%=MOD;
for(int y:ed[x]){
if(y==fa)continue;
DP(y,x);
(ans1+=f[x][1]*f[y][0]+f[x][1]*f[y][1]+f[x][0]*f[y][1])%=MOD;
(ans2+=g[x][1]*f[y][0]+g[x][1]*f[y][1]+g[x][0]*f[y][1]+
f[x][1]*g[y][0]+f[x][1]*g[y][1]+f[x][0]*g[y][1])%=MOD;
(g[x][1]+=v1*g[y][0]+v1*g[y][1]+v0*g[y][1]+
g1*f[y][0]+g1*f[y][1]+g0*f[y][1])%=MOD;
(g[x][0]+=v0*g[y][0]+g0*f[y][0])%=MOD;
(f[x][1]+=v1*f[y][0]+v1*f[y][1]+v0*f[y][1])%=MOD;
(f[x][0]+=v0*f[y][0])%=MOD;
}
return;
}
int lsh[NN];
typedef pair<int,int> pa;
#define x first
#define y second
vector<pa> v1,v2;
int F(int X,vector<pa>&v){
int val=0;
for(int i=0;i<v.size();i++){
int prod1=1,prod2=1;
for(int j=0;j<v.size();j++){
if(i==j)continue;
(prod1*=X-v[j].x)%=MOD;
(prod2*=v[i].x-v[j].x)%=MOD;
}
(val+=v[i].y*prod1%MOD*QP(prod2,MOD-2))%=MOD;
}
return val;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>K;
for(int i=1;i<=n;i++){
cin>>l[i]>>r[i];
mxr=max(mxr,r[i]);
lsh[++lsh[0]]=l[i],lsh[++lsh[0]]=max(1ll,r[i]-K);
lsh[++lsh[0]]=r[i],lsh[++lsh[0]]=max(1ll,l[i]-K);
}
lsh[++lsh[0]]=mxr+1;lsh[++lsh[0]]=1;
sort(lsh+1,lsh+1+lsh[0]);
lsh[0]=unique(lsh+1,lsh+1+lsh[0])-lsh-1;
for(int i=1;i<n;i++){
int l,r;cin>>l>>r;
ed[l].push_back(r);
ed[r].push_back(l);
}
for(int i=1;i<lsh[0];i++){
v1.clear();v2.clear();
for(mn=lsh[i];mn<=min(lsh[i]+n+4,lsh[i+1]-1);mn++){
DP(1,1);
v1.push_back({mn,ans1});
v2.push_back({mn,ans2});
}
ans1=F(lsh[i+1]-1,v1);
ans2=F(lsh[i+1]-1,v2);
}
cout<<ans1<<"\n"<<ans2%MOD;
return 0;
}