一、题目

点此看题

二、解法

这道题很离谱啊,看上去是求一个最大值,其实是把生成树权值为 \(i\) 的个数都给算出来,因为权值很小。

既然是生成树可以考虑矩阵树定理,我们考虑他是求这样一个式子:

\[\sum\prod e_{w_i}
\]

对于这个乘法的理解是很灵活的,只要他能满足直接点值相乘就可以了,比如把边权换成一次多项式来做加法(就是 \(2020\) 年的联合省选题),而这道题是 \(\tt FWT\) 后做矩阵树定理,因为它满足点值相乘。

具体说来,也就是先求出只考虑边权为 \(v\) 的边的矩阵 \(mp[i][j][v]\) ,然后对每个 \(mp[i][j]\) 做 \(\tt FWT\) ,这里的 \(\tt FWT\) 要魔改一下,因为是每一位是独立的,所以每一位做一种 \(\tt FWT\) 是可以的(比如这一位是或运算就做或 \(\tt FWT\))

现在就满足点值相乘了,我们求出每个边权的行列式 \(c[v]\) ,然后对 \(c\) 做同样的 \(\tt IFWT\) ,就得到了每个边权的方案数了。注意我们要一直让所有权值为正才行。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MOD = 1e9+7;
const int N = 75;
const int M = 4100;
#define int long long
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,w,lim,inv,a[N][N][M],r[N][N],c[M];char s[M];
int qkpow(int a,int b)
{
int r=1;
while(b>0)
{
if(b&1) r=r*a%MOD;
a=a*a%MOD;
b>>=1;
}
return r;
}
void fwt(int *a,int n,int op)
{
for(int i=1,b=0;i<n;i<<=1,b++)
{
int p=i<<1;
if(s[b]=='|')
{
for(int j=0;j<n;j+=p)
for(int k=0;k<i;k++)
{
if(op==1) a[i+j+k]=(a[i+j+k]+a[j+k])%MOD;
else a[i+j+k]=(a[i+j+k]-a[j+k]+MOD)%MOD;
}
}
if(s[b]=='&')
{
for(int j=0;j<n;j+=p)
for(int k=0;k<i;k++)
{
if(op==1) a[j+k]=(a[i+j+k]+a[j+k])%MOD;
else a[j+k]=(a[j+k]-a[i+j+k]+MOD)%MOD;
}
}
if(s[b]=='^')
{
for(int j=0;j<n;j+=p)
for(int k=0;k<i;k++)
{
int x=a[j+k],y=a[i+j+k];
a[j+k]=(x+y)%MOD;
a[i+j+k]=(x-y+MOD)%MOD;
if(op==-1)
{
a[j+k]=a[j+k]*inv%MOD;
a[i+j+k]=a[i+j+k]*inv%MOD;
}
}
}
}
}
int zy()
{
int ans=1;
for(int i=1;i<n;i++)
{
for(int j=i+1;j<n;j++)
if(!r[i][i] && r[j][i])
{
ans=MOD-ans;//手误了
swap(r[i],r[j]);
break;
}
if(!r[i][i]) return 0;
int iv=qkpow(r[i][i],MOD-2);
for(int j=i+1;j<n;j++)
{
int t=r[j][i]*iv%MOD;
for(int k=i;k<n;k++)
r[j][k]=(r[j][k]-t*r[i][k]%MOD+MOD)%MOD;
}
ans=ans*r[i][i]%MOD;
}
return ans;
}
signed main()
{
n=read();m=read();inv=(MOD+1)/2;
scanf("%s",s);w=strlen(s);lim=1<<w;
for(int i=1;i<=m;i++)
{
int u=read(),v=read(),c=read();
a[u][v][c]=(a[u][v][c]+MOD-1)%MOD;
a[v][u][c]=(a[v][u][c]+MOD-1)%MOD;
a[u][u][c]++;a[v][v][c]++;
}
for(int i=1;i<n;i++)
for(int j=1;j<n;j++)
fwt(a[i][j],lim,1);
for(int i=0;i<lim;i++)
{
memset(r,0,sizeof r);
for(int j=1;j<n;j++)
for(int k=1;k<n;k++)
r[j][k]=a[j][k][i];
c[i]=zy();
}
fwt(c,lim,-1);
for(int i=lim-1;i>=0;i--)
if(c[i]>0)
{
printf("%lld\n",i);
return 0;
}
puts("-1");
}

[THUPC2019] 找树的更多相关文章

  1. 洛谷 P5406 - [THUPC2019]找树(FWT+矩阵树定理)

    题面传送门 首先看到这道题你必须要有一个很清楚的认识:这题新定义的 \(\oplus\) 符号非常奇怪,也没有什么性质而言,因此无法通过解决最优化问题的思路来解决这个问题,只好按照计数题的思路来解决, ...

  2. poj 1655 Balancing Act(找树的重心)

    Balancing Act POJ - 1655 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的. /* 找树的重心可以用树形dp或 ...

  3. Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value)

    Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,在树的最后一行找到最 ...

  4. LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)

    513. 找树左下角的值 513. Find Bottom Left Tree Value 题目描述 给定一个二叉树,在树的最后一行找到最左边的值. LeetCode513. Find Bottom ...

  5. 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)

    [题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...

  6. Java实现 LeetCode 513 找树左下角的值

    513. 找树左下角的值 给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2 / \ 1 3 输出: 1 示例 2: 输入: 1 / \ 2 3 / / \ 4 5 6 / 7 输 ...

  7. 1090 Highest Price in Supply Chain (25 分)(模拟建树,找树的深度)牛客网过,pat没过

    A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...

  8. Codeforces Beta Round #87 (Div. 2 Only)-Party(DFS找树的深度)

    A company has n employees numbered from 1 to n. Each employee either has no immediate manager or exa ...

  9. poj 1655 找树的重心

    树形DP 求树的重心,即选择一个结点删去,使得分出的 若干棵树的结点数 的最大值最小 #include<map> #include<set> #include<cmath ...

随机推荐

  1. 爬虫入门一 基础知识 以及request

    title: 爬虫入门一 基础知识 以及request date: 2020-03-05 14:43:00 categories: python tags: crawler 爬虫整体概述,基础知识. ...

  2. 基于用户的协同过滤的电影推荐算法(tensorflow)

    数据集: https://grouplens.org/datasets/movielens/ ml-latest-small 协同过滤算法理论基础 https://blog.csdn.net/u012 ...

  3. codeforces 3D (非原创)

    D. Least Cost Bracket Sequence time limit per test 1 second memory limit per test 64 megabytes input ...

  4. codepen 上25个最受欢迎的HTML/CSS代码

    Codepen是一个非常了不起的网站,优设哥在设计师网址导航上也大力推荐过,得到了很多同学的喜爱,也是全球web前端开发人员的圣地! 我搜索了一些时下最好最流行的codepen(仅限于HTML和CSS ...

  5. vue 的 computed 属性在什么时间执行

    vue 的 computed 属性在什么时间执行

  6. VSCode & outline & source code

    VSCode & outline & source code Dart 源码学习 outline 速览 dart-core List class instance-methods ht ...

  7. js bitwise operation all in one

    js bitwise operation all in one 位运算 & 按位与 | 按位或 ^ 按位异或 / XOR let a = 5; // 000000000000000000000 ...

  8. GitHub for VSCode

    GitHub for VSCode A first-party GitHub OAuth application (GitHub for VSCode) with repo and workflow ...

  9. js repeatify & no for loop

    js repeatify & no for loop js repeatify https://www.sitepoint.com/5-typical-javascript-interview ...

  10. SVG & Sprite & symbol & use

    SVG & Sprite & symbol & use https://www.zhangxinxu.com/sp/svgo/ https://www.zhangxinxu.c ...