[THUPC2019] 找树
一、题目
二、解法
这道题很离谱啊,看上去是求一个最大值,其实是把生成树权值为 \(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] 找树的更多相关文章
- 洛谷 P5406 - [THUPC2019]找树(FWT+矩阵树定理)
题面传送门 首先看到这道题你必须要有一个很清楚的认识:这题新定义的 \(\oplus\) 符号非常奇怪,也没有什么性质而言,因此无法通过解决最优化问题的思路来解决这个问题,只好按照计数题的思路来解决, ...
- poj 1655 Balancing Act(找树的重心)
Balancing Act POJ - 1655 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的. /* 找树的重心可以用树形dp或 ...
- Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value)
Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,在树的最后一行找到最 ...
- LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)
513. 找树左下角的值 513. Find Bottom Left Tree Value 题目描述 给定一个二叉树,在树的最后一行找到最左边的值. LeetCode513. Find Bottom ...
- 【题解】#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT)
[题解]#6622. 「THUPC 2019」找树 / findtree(Matrix Tree+FWT) 之前做这道题不理解,有一点走火入魔了,甚至想要一本近世代数来看,然后通过人类智慧思考后发现, ...
- Java实现 LeetCode 513 找树左下角的值
513. 找树左下角的值 给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2 / \ 1 3 输出: 1 示例 2: 输入: 1 / \ 2 3 / / \ 4 5 6 / 7 输 ...
- 1090 Highest Price in Supply Chain (25 分)(模拟建树,找树的深度)牛客网过,pat没过
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...
- 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 ...
- poj 1655 找树的重心
树形DP 求树的重心,即选择一个结点删去,使得分出的 若干棵树的结点数 的最大值最小 #include<map> #include<set> #include<cmath ...
随机推荐
- 爬虫入门一 基础知识 以及request
title: 爬虫入门一 基础知识 以及request date: 2020-03-05 14:43:00 categories: python tags: crawler 爬虫整体概述,基础知识. ...
- 基于用户的协同过滤的电影推荐算法(tensorflow)
数据集: https://grouplens.org/datasets/movielens/ ml-latest-small 协同过滤算法理论基础 https://blog.csdn.net/u012 ...
- codeforces 3D (非原创)
D. Least Cost Bracket Sequence time limit per test 1 second memory limit per test 64 megabytes input ...
- codepen 上25个最受欢迎的HTML/CSS代码
Codepen是一个非常了不起的网站,优设哥在设计师网址导航上也大力推荐过,得到了很多同学的喜爱,也是全球web前端开发人员的圣地! 我搜索了一些时下最好最流行的codepen(仅限于HTML和CSS ...
- vue 的 computed 属性在什么时间执行
vue 的 computed 属性在什么时间执行
- VSCode & outline & source code
VSCode & outline & source code Dart 源码学习 outline 速览 dart-core List class instance-methods ht ...
- js bitwise operation all in one
js bitwise operation all in one 位运算 & 按位与 | 按位或 ^ 按位异或 / XOR let a = 5; // 000000000000000000000 ...
- GitHub for VSCode
GitHub for VSCode A first-party GitHub OAuth application (GitHub for VSCode) with repo and workflow ...
- js repeatify & no for loop
js repeatify & no for loop js repeatify https://www.sitepoint.com/5-typical-javascript-interview ...
- SVG & Sprite & symbol & use
SVG & Sprite & symbol & use https://www.zhangxinxu.com/sp/svgo/ https://www.zhangxinxu.c ...