传送门
HEOI的题好珂怕啊(各种意义上)
然后考虑树形dp,以大于为例
设$f[i][j]$表示$i$这个节点在子树中排名第$j$位时的总方案数(因为实际只与相对大小有关,与实际数值无关)
我们考虑如果从当前子树中弄出$k$个节点,其他子树中弄出$j-1$个节点,那么当前节点的大小排名就是$k+j$
然后考虑一下,如果我们不看这个子树,根节点排在第$j$个,方案数是$f[i][j]$,如果只看此子树,此子树的根就是根节点的儿子,它在此子树中的排名可能是$1,2,...k$,那么我们就需要记录一下前缀和
然后考虑合并排列
对于小于根节点的,选出$j-1$个非此子树,对于大于根节点的,选出$sum[x]-1$个非此子树里弄出来的,那么就是一个组合问题了
ps:因为dp的时候会有4个1e9相乘所以要模四次
然后上我这个卡常卡到丧心病狂的代码
1 // luogu-judger-enable-o2 2 //minamoto 3 #include<iostream> 4 #include<cstdio> 5 #include<cstring> 6 #define ll long long 7 using namespace std; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf; 10 inline int read(){ 11 #define num ch-'0' 12 char ch;bool flag=0;int res; 13 while(!isdigit(ch=getc())) 14 (ch=='-')&&(flag=true); 15 for(res=num;isdigit(ch=getc());res=res*10+num); 16 (flag)&&(res=-res); 17 #undef num 18 return res; 19 } 20 inline int getop(){ 21 char ch;while((ch=getc())!='<'&&ch!='>');return ch=='<'?1:-1; 22 } 23 void print(int x){ 24 if(x>=10) print(x / 10); 25 putchar('0'+x%10); 26 } 27 const int N=1005,mod=1e9+7; 28 int n,tot;ll tmp[N]; 29 int f[N][N],g[N][N],c[N][N]; 30 int head[N],ver[N<<1],Next[N<<1],sum[N],edge[N<<1]; 31 inline void init(){ 32 c[0][0]=1; 33 for(int i=1;i<=1000;++i){ 34 c[i][0]=1; 35 for(int j=1;j<=i;++j) 36 c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; 37 } 38 } 39 inline void clear(){ 40 memset(head,0,sizeof(head)); 41 tot=0; 42 } 43 inline void add(int u,int v,int e){ 44 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e; 45 } 46 void dfs(int u,int fa){ 47 memset(g[u],0,sizeof(g[u])),memset(f[u],0,sizeof(f[u])); 48 g[u][1]=f[u][1]=sum[u]=1; 49 for(int i=head[u];i;i=Next[i]){ 50 int v=ver[i],e=edge[i]; 51 if(v==fa) continue; 52 dfs(v,u); 53 memset(tmp,0,sizeof(tmp)); 54 for(int j=1;j<=sum[u];++j) 55 for(int k=0;k<=sum[v];++k){ 56 if(~e) 57 tmp[j+k]+=1ll*f[u][j]*g[v][k]%mod 58 *c[j+k-1][j-1]%mod*c[sum[u]+sum[v]-j-k][sum[u]-j]%mod; 59 else tmp[j+k]+=1ll*f[u][j]*(g[v][sum[v]]-g[v][k]+mod)%mod 60 *c[j+k-1][j-1]%mod*c[sum[u]+sum[v]-j-k][sum[u]-j]%mod; 61 } 62 sum[u]+=sum[v]; 63 for(int j=1;j<=sum[u];++j) 64 f[u][j]=tmp[j]%mod,g[u][j]=(g[u][j-1]+f[u][j])%mod; 65 } 66 } 67 int main(){ 68 // freopen("testdata.in","r",stdin); 69 int T=read();init(); 70 while(T--){ 71 clear();n=read(); 72 for(int i=1,u,v,e;i<n;++i){ 73 u=read(),e=getop(),v=read(); 74 add(u,v,e),add(v,u,-e); 75 } 76 dfs(1,-1); 77 print(g[1][sum[1]]),putchar(10); 78 } 79 return 0; 80 }
转载于:https://www.cnblogs.com/bztMinamoto/p/9648167.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/107867.html