zoukankan      html  css  js  c++  java
  • 6541. 【GDOI2020模拟4.4】Permutation

    题目描述


    题解

    迫真签到题

    前几天做过类似的,只不过要求的是相邻的lca,所以要n^3考虑具体每一段

    对于这题不行

    显然每个子树内的段=边权/2,并且合并时要求不能合并相同子树内的段

    容斥一下,系数是(-1)^合并相同子树内的段再乘上组合数

    假设当前不为整棵树的根,设第子树i原有p[i]段,合并后变成q[i]段,最后再合并成k段

    则贡献为

    (huge frac{sum q[i]+1}{prod q[i]!}C_{(sum q[i]+1)-1}^{k-1}prod(-1)^{p[i]-q[i]}C_{p[i]-1}^{q[i]-1})

    就是把合并完的随便放再合并成k段,注意要考虑当前节点

    手玩一下发现当合并段数>0时容斥系数之和=0,因此容斥后的会在每个节点处合并成真正的方案数

    把式子拆开背包

    如果当前是整棵树的根就硬点为第一段,最后乘上n的轮换

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define C(n,m) (jc[n]*Jc[m]%mod*Jc[(n)-(m)]%mod)
    #define ll long long
    #define file
    using namespace std;
    
    int a[10001][3],ls[5001],size[5001],n,mod,Mod,i,j,k,l,len;
    ll f[5001],g[5001],G[5001],jc[5001],Jc[5001],w[5001],ans;
    
    ll qpower(ll a,int b) {ll ans=1;while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
    void New(int x,int y,int z) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;a[len][2]=z;}
    
    void dfs(int Fa,int t,int Ls)
    {
    	int i;
    	ll s;
    	
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa)
    	dfs(t,a[i][0],a[i][2]);
    	
    	memset(g,0,sizeof(g));g[1]=size[t]=1;
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa)
    	{
    		memset(G,0,(size[t]+size[a[i][0]]+1)*8);
    		
    		fo(j,1,size[t])
    		{
    			fo(k,1,a[i][2])
    			G[j+k]=(G[j+k]+g[j]*f[a[i][0]]%mod*((a[i][2]-k)&1?-1:1)*C(a[i][2]-1,k-1)%mod*Jc[k])%mod;
    		}
    		size[t]+=size[a[i][0]];
    		
    		memcpy(g,G,(size[t]+1)*8);
    	}
    	
    	if (Fa)
    	{fo(i,Ls,size[t]) f[t]=(f[t]+g[i]*jc[i]%mod*C(i-1,Ls-1))%mod;}
    	else
    	{fo(i,1,size[t]) ans=(ans+g[i]*jc[i-1]%mod)%mod;}
    }
    
    int main()
    {
    	freopen("permutation.in","r",stdin);
    	#ifdef file
    	freopen("permutation.out","w",stdout);
    	#endif
    	
    	scanf("%d%d",&n,&mod),Mod=mod-2;
    	jc[0]=jc[1]=Jc[0]=Jc[1]=w[1]=1;
    	fo(i,2,n) scanf("%d%d%d",&j,&k,&l),l/=2,New(j,k,l),New(k,j,l),w[i]=mod-w[mod%i]*(mod/i)%mod,jc[i]=jc[i-1]*i%mod,Jc[i]=Jc[i-1]*w[i]%mod;
    	
    	dfs(0,1,-1);
    	
    	printf("%lld
    ",(ans+mod)%mod*n%mod);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    6-Python爬虫-分布式爬虫/Redis
    ES 查询时 排序报错(fielddata is disabled on text fileds by default ... )解决方法
    Intellij Idea webstorm 激活
    Intellij Idea 配置jdk
    java 获取(格式化)日期格式
    js 跳转 XSS漏洞 预防
    CSS去掉背景颜色
    js对象无法当成参数传递 解决方法
    Elasticsearch java api
    java多条件查询SQL语句拼接的小技巧
  • 原文地址:https://www.cnblogs.com/gmh77/p/12684324.html
Copyright © 2011-2022 走看看