P6803-[CEOI2020]星际迷航【博弈论,dp,矩阵乘法】

正题

题目链接:https://www.luogu.com.cn/problem/P6803


题目大意

给出一棵nnn个点的树,把它复制出D+1D+1D+1层,编号为[0,D][0,D][0,D],然后每一层随机一个点向下一层随机一个点连边。

然后从第000层的111号点出发,两个人轮流操作走向一个之前没有走过的点,求有多少种连边方案使得先手必胜。

1≤n≤105,1≤D≤10181\leq n\leq 10^5,1\leq D\leq 10^{18}1n105,1D1018


解题思路

我们先只考虑连到下一层的那个点是必胜还是必败的。

显然,连接的下一层的点如果是必胜的,那么局面不会有任何改变。而如果连接的是必败的点,那么原本必败的情况就会变成必胜的情况。

考虑对于每个点算出Gx,0/1G_{x,0/1}Gx,0/1表示从xxx出发的情况,如果连接的下层点必败,这一层有多少种连边情况会先手必胜/先手必败。

这个东西虽然比较麻烦,但是可以通过换根dpdpdp求出。

然后把所有点的求个和得到S0,0/1S_{0,0/1}S0,0/1表示下一层连接先手必败的点,这一层得到胜/负的方案。

同样的通过每一个点为根时树的胜负情况得到S1,0/1S_{1,0/1}S1,0/1表示下一层连接先手必胜的点(局面不会改变),这一层得到胜/负的方案。

这样做DDD层我们就可以直接矩阵乘法了。

时间复杂度:O(n+log⁡D)O(n+\log D)O(n+logD)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const ll N=1e5+10,S=2,P=1e9+7;
struct Matrix{ll a[S][S];
}s,ans,c;
Matrix operator*(const Matrix &a,const Matrix &b){memset(c.a,0,sizeof(c.a));for(ll i=0;i<S;i++)for(ll j=0;j<S;j++)for(ll k=0;k<S;k++)(c.a[i][j]+=a.a[i][k]*b.a[k][j]%P)%=P;return c;
}
struct node{ll to,next;
}a[N<<1];
ll n,d,tot,ls[N],g[N][2];
bool f[N];vector<ll> q[N];
void addl(ll x,ll y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void dfs(ll x,ll fa){ll p=0;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x);f[x]|=!f[y];if(!f[y])p=(p?-1:y);g[x][1]+=g[y][0];g[x][0]+=g[y][1];}if(p==-1)g[x][1]+=g[x][0];else if(p>0)g[x][1]+=g[x][0]-g[p][1];if(p==-1)g[x][0]=0;else if(p>0)g[x][0]=g[p][1];g[x][1]++;return;
}
void solve(ll x,ll fa,ll p,ll s0,ll s1){if(!p)q[x].push_back(fa);for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;if(!f[y]&&q[x].size()<3)q[x].push_back(y);s0+=g[y][1];s1+=g[y][0];}if(!q[x].size())p=0;else if(q[x].size()==1)p=q[x][0];else p=-1;int pg0=g[x][0],pg1=g[x][1];g[x][0]=s0,g[x][1]=s1;if(p==-1)g[x][1]+=g[x][0],g[x][0]=0;else if(p>0)g[x][1]+=g[x][0]-g[p][1],g[x][0]=g[p][1];g[x][1]++;ll _f=(p?1:0);ans.a[0][_f]++;s.a[0][0]+=g[x][0];s.a[0][1]+=g[x][1];s.a[1][0]+=(!_f)*n;s.a[1][1]+=_f*n;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;if(!q[x].size())p=0;else if(q[x].size()==1){if(q[x][0]==y)p=0;else p=q[x][0];}else if(q[x].size()==2){if(q[x][0]==y)p=q[x][1];else if(q[x][1]==y)p=q[x][0];else p=-1;}else p=-1;g[x][0]=s0-g[y][1];g[x][1]=s1-g[y][0];if(p==-1)g[x][1]+=g[x][0],g[x][0]=0;else if(p>0)g[x][1]+=g[x][0]-g[p][1],g[x][0]=g[p][1];g[x][1]++;solve(y,x,p?1:0,g[x][1],g[x][0]);}g[x][0]=pg0;g[x][1]=pg1;return;
}
signed main()
{scanf("%lld%lld",&n,&d);for(ll i=1,x,y;i<n;i++){scanf("%lld%lld",&x,&y);
//		x=i+1;y=(i+1)/2;addl(x,y);addl(y,x);}dfs(1,0);ll A=g[1][1];solve(1,0,1,0,0);s.a[0][0]%=P;s.a[0][1]%=P;s.a[1][0]%=P;s.a[1][1]%=P;d--;while(d){if(d&1)ans=ans*s;s=s*s;d>>=1;}ll answer=A*ans.a[0][0]%P;(answer+=f[1]*n*ans.a[0][1]%P)%=P;printf("%lld\n",answer);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

潘淳:国士无双《微软技术俱乐部(苏州)成立大会暨微软技术交流会介绍》附专题视频...

题记&#xff1a;凡我赶不上的&#xff0c;我就在未来等他&#xff0c;随时等待捕捉那个趋势的的到来。2019年立一个FLAG&#xff0c;加入一个成长性组织&#xff0c;一个能让我学习使我成长的平台。2019年你和我都将亲历这个组织的到来&#xff0c;一个属于苏州程序员自己的大…

ASP.NET Core中借助CSRedis实现安全高效的分布式锁

引言最近回头看了看开发的.NET Core 2.1项目的复盘总结&#xff0c;其中在多处用到Redis实现的分布式锁&#xff0c;虽然在OnResultExecuting方法中做了防止死锁的处理&#xff0c;但在某些场景下还是会发生死锁的问题&#xff0c;下面我只展示部分代码&#xff1a;问题&#x…

L Machining Disc Rotors

L Machining Disc Rotors 题意&#xff1a; 圆心为(0,0)半径为R的圆&#xff0c;现在被被n个互不相交的圆切割(圆心和半径会给出)&#xff0c;保证这n个彼此之间不会交叉&#xff0c;保证n个圆中不会有某个包含整个大圆的情况。问切割后大圆剩余部分的直径&#xff08;即两点…

线性代数二之矩阵加速DP——数学作业,Arc of Dream

矩阵加速数学作业descriptionsolutioncodeArc of Dreamdescriptionsolutioncode数学作业 description solution dpdpdp状态转移方程&#xff0c;dpidpi−1∗10lenii(modM)dp_{i}dp_{i-1}*10^{len_i}i\pmod Mdpi​dpi−1​∗10leni​i(modM) nnn巨大&#xff0c;分段矩阵加速 …

pjudge#21655-[PR #5]双向奔赴【状压dp】

正题 题目链接:http://pjudge.ac/contest/951/problem/21655 题目大意 给出一张nnn个点的简单无向图&#xff0c;每条边的两个方向具有不同权值。求一个权值和最小的定向方案使得整张图强连通。 1≤n≤18,−1≤ai,j≤1061\leq n\leq 18,-1\leq a_{i,j}\leq 10^61≤n≤18,−1≤…

YBTOJ洛谷P2387: 魔法森林(LCT)

解析 LCT从板子到算法的入门题吧 有一些不知道的很实用的技巧 把边按a排序从小到大加入边 那么我们只需要维护当前1-n路径上的b的最小值即可 如果这条边两端点本来不连通&#xff0c;就直接link 否则找到路径上b最大的一条边&#xff0c;断掉&#xff0c;再加入当前边&#x…

Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】

接着上一篇Shadow Properties之美&#xff08;一&#xff09;&#xff0c;我们来继续举一个有点啰嗦的栗子。先看简单需求&#xff1a;某HR系统&#xff0c;需要记录员工资料。需要记录的资料有&#xff1a;员工号&#xff08;规则&#xff1a;分公司所在城市拼音首字母&#x…

K - Let the Flames Begin

K - Let the Flames Begin 题意&#xff1a; n个人围成一个环&#xff0c;编号分别是1~n&#xff0c;从第一个人开始报数&#xff0c;报道k的人被移除&#xff0c;然后下一个人从1重新报&#xff0c;一直这样进行。问第m给被移除的人报数是多少&#xff1f; 一共T组数据&…

CF1276F-Asterisk Substrings【SAM,线段树合并】

正题 题目链接:https://www.luogu.com.cn/problem/CF1276F 题目大意 给出一个长度为nnn的字符串SSS&#xff0c;现在依次进行如下操作 取出SSS的一个子串TTT。将TTT中的一个字符替换成∗*∗号&#xff08;也可以不替换&#xff09; 求最后有多少种不同的TTT。 解题思路 发…

线性代数三之状压DP的矩阵加速——Quad Tiling,Bus公交线路

状压与矩阵加速的藕断丝连Quad Tilingdescriptionsolutioncode[Hnoi2010]Bus 公交线路descriptionsolutioncodeQuad Tiling description solution 设dpi,S:dp_{i,S}:dpi,S​: iii列的状态为SSS的方案数&#xff0c;最后答案为dpn,(1<<4)−1dp_{n,(1<<4)-1}dpn,(…

codeforces:812(div2):总结

前言 比较水的一场比赛 E题几乎是一本通原题而我还是不会做qwq A - Sagheer and Crossroads 有一个十字路口&#xff0c;给出四个路口的车是否可以左转/右转/直行&#xff0c;并且给出每个路口的行人是否可以通过&#xff0c;求是否出现车和人冲突的情况 阅读理解题&#xff…

如何在ASP.NET Core程序启动时运行异步任务(2)

原文&#xff1a;Running async tasks on app startup in ASP.NET Core (Part 2)作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu在我的上一篇博客中&#xff0c;我介绍了如何在ASP.NET Core应用程序启动时运行一些一次性异步任务。本篇博客将继续讨论上一篇的内容&…

Gym 102798A Golden Spirit

VJ链接 题意&#xff1a; 河的两岸各有n个人&#xff0c;中间有个桥&#xff0c;过桥时间为t&#xff0c;所有人过桥后要休息x时间&#xff0c;你每次可以带一个人过桥&#xff08;每次最多只能带一个人&#xff09;&#xff0c;问将所有人带到对岸并带回来&#xff0c;最短需…

P8347-「Wdoi-6」另一侧的月【博弈论,结论】

正题 题目链接:https://www.luogu.com.cn/problem/P8347 题目大意 给出一棵树&#xff0c;两个人轮流操作。 操作者可以选择一个点删除&#xff0c;然后选择一个剩下的连通块&#xff0c;删除其他连通块。 操作完成后只剩下一个点的人失败&#xff0c;求是否先手必败。 1≤…

线性代数四之动态DP(广义矩阵加速)——Can you answer these queries III,保卫王国

动态DP——广义矩阵加速SP1716 GSS3 - Can you answer these queries IIIdescriptionsolutioncode[NOIP2018 提高组] 保卫王国descriptionsolutioncode动态DP能矩阵加速要满足外层操作符对内层操作符具有分配率加法对于乘法就具有分配率(ab)*ca*cb*c SP1716 GSS3 - Can you a…

洛谷P4219 大融合(LCT、虚子树)

解析 本题需要用LCT维护子树大小 然后我就不会了 然后我就用树剖水过去了 又快又好写&#xff0c;真香 现在详细聊聊如何用LCT维护子树信息 每个结点再定义一个新的变量记录所有虚儿子的信息 然后…完了&#xff1f; 告别盲目pushup&#xff0c;我们来详细聊聊在哪里需要更新…

.Net Core跨平台应用研究-HelloArm(串口篇)

引言为了验证采用dotnet core技术开发的物联网设备数据采集接入服务应用是否能在高性价比的linux嵌入式平台运行&#xff0c;针对dotnet core应用程序进行嵌入式linux环境的发布部署运行验证研究。硬件环境硬件系统经过对比筛选&#xff0c;选用了友善之臂出品的NanoPC-T3 Plus…

H - Message Bomb Gym - 102798H

H - Message Bomb Gym - 102798H 题意&#xff1a; 有n个团队&#xff0c;m个人&#xff0c;s个操作 操作1&#xff1a;学生x加入y团队 操作2&#xff1a;学生x推出y团队 操作3&#xff1a;学生x在团队y发送一个信号&#xff0c;在团队y内的所有成员&#xff08;除了x&#x…

Loj#3005-「JOISC 2015 Day 4」Limited Memory【交互题】

正题 题目链接:https://loj.ac/p/3005 题目大意 有一个长度为nnn的括号串SSS&#xff0c;其中包括[]和<>两种括号类型&#xff0c;一个合法的括号串要求同类型的括号一一对应。 你每次可以询问SSS中的一个字符并且传递一个[0,222)[0,2^{22})[0,222)的数字到下一次。 …

[数论系列一]C Looooops,跳跳棋,The Luckiest number,CF906D Power Tower,Minimal Power of Prime,仪仗队,LCMSUM

文章目录C Looooopsdescriptionsolutioncode跳跳棋descriptionsolutioncodeThe Luckiest numberdescriptionsolutioncodeCF906D Power TowerdescriptionsolutioncodeMinimal Power of Primedescriptionsolutioncode[SDOI2008]仪仗队descriptionsolutioncodeLCMSUMdescriptionso…