Solution -「多校联训」行列式
\(\mathcal{Description}\)
Link.
给定 \(x,\{d_i\}_{i=1}^n,\{p_i\}_{i=2}^n,\{b_i\}_{i=2}^n,\{c_i\}_{i=2}^n\),构造矩阵 \(A=(a_{ij})_{n\times n}\):
b_j,&i=p_j\\
c_i,&j=p_i\\
d_i,&i=j\\
x,&\text{otherwise}
\end{cases}.
\]
求 \(\det A\)。
\(n\le10^6\),\(p_i\in[1,i)\)。
\(\mathcal{Solution}\)
\(p_i\in[1,i),~i=2,3,\dots,n\)。
这是什么?这是树!
在这样意识流的思考下,我们选择将 \(A\) 看做邻接矩阵,那么自然地区分出了三类边:
- 树边,以 \(1\) 位根,父亲到儿子的边权是 \(b\),儿子到父亲的边权是 \(c\);
- 自环,边权为 \(d\);
- 非树边,边权为 \(x\)。
矩阵中有大面积的常数 \(x\),利用 trick,从行列式的定义式的角度抵消大量贡献。具体地,令 \(X=(x)_{n\times n},Y=A-X\),则
\det A&=\det (X+Y)\\
&=\sum_{\sigma}(-1)^{\tau(\sigma)}\prod_{i=1}^n(x+y_{i\sigma_i}).
\end{aligned}
\]
此番强行构造出二项式相乘的形式,若累乘式中至少 \(2\) 项选择了 \(x\),不妨设选择 \(x\) 的位置为 \(\{q_1,q_2,\cdots,q_k\}~(k>1)\),那么于 \(\sigma\) 中交换 \(\sigma_{q_1}\) 和 \(\sigma_{q_2}\) 的位置得到 \(\sigma'\),在新的累乘式中同样选择 \(\{q_1,q_2,\cdots,q_k\}\) 为 \(x\),而 \((-1)^{\tau(\sigma)+\tau(\sigma')}=0\),并且 \(\sigma\) 与 \(\sigma'\) 两两对应抵消,所以这样的方案是没有贡献的!
回到图上,考虑 \(\prod_{i=1}^n a_{i\sigma_i}\) 的组合意义:每个结点 \(i\) 选择邻接边 \(\lang i,\sigma_i\rang\),得到边权的乘积。所选的边显然构成若干简单环,而在排除至多出现一次的含有非树边 \(x\) 的环,其余环必然是自环或树边二元环!(注意含非树边的环亦可为这两种情况。)
进一步,尝试树上 DP 求解这一形象问题。在计算逆序对 \(\tau(\sigma)\) 时,利用结论
设 \(\sigma\) 轮换分解后得到偶排列的的个数为 \(c\),则 \((-1)^c=(-1)^{\tau(\sigma)}\)。(易证。)
可以将 \((-1)\) 的贡献直接乘到状态的值中。具体来说,对于 \(u\) 点,状态应有:
- 子树内无 \(x\) 环;\(u\) 在子树内的环中;
- 子树内有 \(x\) 环;\(u\) 在子树内的环中;
- 子树内无 \(x\) 环;\(u\) 不在子树内的环中且不在 \(x\) 环中;
- 子树内有 \(x\) 环;\(u\) 不在子树内的环中且不在 \(x\) 环中;
- 子树内无 \(x\) 环;\(u\) 在顶点高于 \(u\) 的 \(x\) 环中,且选择向上的树边;
- 子树内无 \(x\) 环;\(u\) 在顶点高于 \(u\) 的 \(x\) 环中,且选择向下的树边。
六种情况,分别写出转移式子即可。(当然也可以用多维状态来让思路更清晰。)
最终,复杂度 \(\mathcal O(n)\)。
\(\mathcal{Code}\)
/*~Rainybunny~*/
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
inline int rint() {
int x = 0, f = 1, s = getchar();
for ( ; s < '0' || '9' < s; s = getchar() ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar() ) x = x * 10 + ( s ^ '0' );
return x * f;
}
template<typename Tp>
inline void wint( Tp x ) {
if ( x < 0 ) putchar( '-' ), x = -x;
if ( 9 < x ) wint( x / 10 );
putchar( x % 10 ^ '0' );
}
const int MAXN = 1e6, MOD = 1e9 + 7;
int n, ecnt, head[MAXN + 5], x, b[MAXN + 5], c[MAXN + 5], d[MAXN + 5];
int f[MAXN + 5][6];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline void link( const int s, const int t ) {
graph[++ecnt] = { t, head[s] }, head[s] = ecnt;
}
inline void solve( const int u ) {
f[u][0] = f[u][4] = f[u][5] = 1, f[u][1] = d[u];
for ( int i = head[u], v; i; i = graph[i].nxt ) {
solve( v = graph[i].to );
static int tmp[6];
tmp[0] = mul( f[u][0], f[v][1] );
tmp[1] = mul( f[u][1], f[v][1] );
subeq( tmp[1], mul( mul( f[u][0], f[v][0] ), mul( b[v], c[v] ) ) );
tmp[2] = mul( f[u][2], f[v][1] );
addeq( tmp[2], mul( f[u][0], f[v][3] ) );
tmp[3] = mul( f[u][3], f[v][1] );
addeq( tmp[3], mul( f[u][1], f[v][3] ) );
subeq( tmp[3], mul( mul( f[u][0], f[v][2] ), mul( b[v], c[v] ) ) );
subeq( tmp[3], mul( mul( f[u][2], f[v][0] ), mul( b[v], c[v] ) ) );
subeq( tmp[3], mul( mul( f[u][4], f[v][5] ), mul( x, c[v] ) ) );
subeq( tmp[3], mul( mul( f[u][5], f[v][4] ), mul( x, b[v] ) ) );
tmp[4] = mul( f[u][4], f[v][1] );
subeq( tmp[4], mul( mul( f[u][0], f[v][4] ), b[v] ) );
tmp[5] = mul( f[u][5], f[v][1] );
subeq( tmp[5], mul( mul( f[u][0], f[v][5] ), c[v] ) );
rep ( j, 0, 5 ) f[u][j] = tmp[j];
}
addeq( f[u][3], mul( x, f[u][0] ) );
}
int main() {
freopen( "B.in", "r", stdin );
freopen( "B.out", "w", stdout );
n = rint(), x = rint();
rep ( i, 1, n ) d[i] = sub( rint(), x );
rep ( i, 2, n ) {
link( rint(), i ), b[i] = sub( rint(), x ), c[i] = sub( rint(), x );
}
solve( 1 );
wint( add( f[1][1], f[1][3] ) ), putchar( '\n' );
return 0;
}
Solution -「多校联训」行列式的更多相关文章
- Solution -「多校联训」排水系统
\(\mathcal{Description}\) Link. 在 NOIP 2020 A 的基础上,每条边赋权值 \(a_i\),随机恰好一条边断掉,第 \(i\) 条段的概率正比于 \(a ...
- Solution -「多校联训」I Love Random
\(\mathcal{Description}\) 给定排列 \(\{p_n\}\),可以在其上进行若干次操作,每次选取 \([l,r]\),把其中所有元素变为原区间最小值,求能够得到的所有不同序 ...
- Solution -「多校联训」签到题
\(\mathcal{Description}\) Link. 给定二分图 \(G=(X\cup Y,E)\),求对于边的一个染色 \(f:E\rightarrow\{1,2,\dots,c\ ...
- Solution -「多校联训」朝鲜时蔬
\(\mathcal{Description}\) Link. 破案了,朝鲜时蔬 = 超现实树!(指写得像那什么一样的题面. 对于整数集 \(X\),定义其 好子集 为满足 \(Y\sub ...
- Solution -「多校联训」消失的运算符
\(\mathcal{Description}\) Link. 给定长度为 \(n\) 的合法表达式序列 \(s\),其中数字仅有一位正数,运算符仅有 - 作为占位.求将其中恰好 \(k\) ...
- Solution -「多校联训」假人
\(\mathcal{Description}\) Link. 一种物品有 长度 和 权值 两种属性,现给定 \(n\) 组物品,第 \(i\) 组有 \(k_i\) 个,分别为 \((1,a ...
- Solution -「多校联训」古老的序列问题
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\),和 \(q\) 次形如 \([L,R]\) 的询问,每次回答 \[\sum_{[l,r]\su ...
- Solution -「多校联训」Sample
\(\mathcal{Description}\) Link (稍作简化:)对于变量 \(p_{1..n}\),满足 \(p_i\in[0,1],~\sum p_i=1\) 时,求 \(\ma ...
- Solution -「多校联训」光影交错
\(\mathcal{Description}\) Link. 一个游戏包含若干次卡牌抽取,每次以 \(p_l\) 的概率得到 \(+1\),\(p_d\) 的概率得到 \(-1\),否则得到 ...
随机推荐
- MapReduce和Hive学习文档链接学习顺序
1.<CentOS6.5下安装Hadoop-2.7.3(图解教程)> https://www.toutiao.com/i6627365258090512909/ 2.<CentOS6 ...
- 金融云原生漫谈(三)|银行云原生基础设施构建:裸金属VS虚拟机
在金融行业数字化转型的驱动下,国有银行.股份制银行和各级商业银行也纷纷步入容器化的进程. 如果以容器云上生产为目标,那么整个容器云平台的设计.建设和优化对于银行来说是一个巨大的挑战.如何更好地利用 ...
- nginx代理图片上传以及访问 nginx 图片上传完整版
nginx代理图片上传 首先需要利用nginx代理图片访问参考 https://www.cnblogs.com/TJ21/p/12609017.html 编写接受文件的controller 1 @Po ...
- python基本数据类型与操作
一.变量 1.变量的三要素:变量名.变量值.变量数据类型 2.定义变量格式:变量名称 = 变量值 3.输出变量:print(变量名) """ 变量 "" ...
- Error building SqlSession. ### The error may exist in dao/UserMapper.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration(2 字节的 UTF-8 序列的字节 2 无效。)
关于在学习Mybatis框架时运行报错 Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error building ...
- JVM调优方法
目 录 目 录 I 诠释JVM调优 1 第1章 JVM内存模型及垃圾收集算法 1 1.1 根据Java虚拟机规范,JVM将内存划分为 1 1.2 垃圾回收算法 1 第2章 内存泄漏及解决方法 2 2. ...
- 新年好 takoyaki,期待再次与你相见
一.序 今天是中国农历一年的最后一天,往年都叫年三十,今年没有三十,最后一天是二十九.厨房的柴火味.窗外的鞭炮声还有不远处传来的说笑声,一切都是熟悉味道,新年到了,家乡热闹起来了.平常左邻右舍都是看不 ...
- java解洛谷P1011车站问题
车站每站的上车人数,下车人数,剩余人数都组成了斐波那契数列 此代码只计算了剩余人数的情况,所以在输入需要总站数量时会-1取上一站的剩余人数 (最后一站会全部下车,没有上车人数) 每一站的剩余人数都可以 ...
- CSS之常见布局|常用单位|水平垂直居中
常见布局: 1. 流式布局:百分比布局,宽高.margin.pinding都是百分比 2. 固定布局:盒子的宽高固定,如:margin.padding等 3. 浮动布局:float 4. 弹性布局:f ...
- 使用Hot Chocolate和.NET 6构建GraphQL应用(5) —— 实现Query过滤功能
系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 对于查询来说,还有一大需求是针对查询的数据进行过滤,本篇文章我们准备实现GraphQL中基本的查询过滤. 思 ...