codeforces gym-101745 C-Infinite Graph Game 分块

题意

题目链接
给出一个顶点带权无向图。
定义访问操作:访问一个点,就要把与这个点相邻的点的权值全部都加到答案里去,然后给这个顶点的权值/2。现在给出一个无穷的访问序列中的一个循环节,求最终答案的极限是多少。
注意:本题是在模意义下。

题解

数据范围 ≤ 100000
我们定义一个sumsum数组,其中sum[v]sum[v]表示与vv顶点相邻的所有顶点的权值和。
这样我们扫描一个循环节,只需要把当前顶点v的sum[v]加入到答案里面去就好了,然后我们要给顶点vv的权值减半,并且还要更新顶点v相邻的所有点的sumsum
这个思路看起来没有问题,但是问题来了,更新顶点v相邻的所有点的sumsum值的时候,如果每个点相邻的点都有99999个这么多。而循环节长度又有100000个这么长,时间复杂度显然就会爆炸了。

我们现在需要一个O(nn)O(nn)的算法。

我们把顶点进行分类,按照这个顶点的度数进行分。
degv>300degv>300的点,我们把它看作是big点,如果某个点u与big点点相临,那么这个u点的sum[u]sum[u]中不应该包含big点的权值,这样的话,big点就不需要更新周围点的sum值了。

degv300degv≤300的点,我们把它看作是small点,如果某个点u与small点相邻,那么这个u点的sum[u]sum[u]中应该包含small点的权值,并且访问small点时候,也应该从small点出发更新相邻点的sumsum值。

这样的话,更新操作的时间复杂度就变成了O(k300)O(k∗300)
我们继续来看询问操作,每次到一个点的时候,把这个点的sum[u]sum[u]加到答案里去,并且还要把这个点相邻的big点的权值加到答案里去(因为此时sum[u]sum[u]中并不包含big点的权值)

m是边数,最大为100000
每个点最多有m300=300m300=300个big点。因此询问的时间复杂度也是O(k300)O(k∗300)
这样总的时间复杂度就是O(k300)O(k∗300)

这道题还没有做完

我们刚刚求的只是一轮循环节的答案,我们现在需要求极限值。

而第一轮的答案与第二轮的答案没有任何比例关系。

这迫使我们去寻找组成第一轮答案的部分与组成第二轮答案的部分之间有没有关系。

我们设顶点vv,初始权值为val[v],在第一轮中的贡献为x1x1,那么肯定有x1=pval[v]x1=p∗val[v],其中p代表一个比例系数。

在第一轮以后,vv的权值变成了val[v]12cnt[v],其中cnt[v]cnt[v]表示的是这个vv点在循环节中出现的次数。

第二轮中v对答案的贡献是x2x2,那么x2=pval[v]12cnt[v]x2=p∗val[v]∗12cnt[v]

这样推导下去,并对所有的xx求和得到

sumx=pval[v]12cnt[v]

关键点来了!!!
注意看sumxsumxx1x1的形式关系,发现就相当于用val[v]12cnt[v]val[v]1−2−cnt[v]替换了val[v]val[v]
因此,我们想到了解题方案,就是一开始就对所有点的权值按照这个关系进行替换,然后跑一轮循环节,得到的答案就是要求的极限。

这道题还没有做完
这道题不一定会有极限,如果没有极限,要输出-1。
怎么判定有没有极限呢?
如果一个点被访问了,那么周围点的权值都会被加到答案里面去,所以周围点的权值必须减少,如果发现一个点被访问了,而在循环节结束后,还有一个周围相邻的点的权值没有被减少,那么意味着肯定不会收敛。

终于讲完了,如果觉得好就点个赞吧。

代码

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
#define pr(x) cout<<#x<<':'<<x<<endl
const int maxn = 100007;
ll n,m,k,val[maxn],s[maxn];
vector<int> G[maxn],heavy[maxn];
int deg[maxn],cnt[maxn],vis[maxn],big[maxn];
ll sum[maxn],ans[maxn];
const ll mod = 1e9+7;
long long powmod(long long x, long long p){long long res = 1;while(p > 0){if(p % 2 == 1) res = res * x % mod;x = x * x % mod;p >>= 1;}return res;
}
ll mi[maxn],inv[maxn];
int main(){inv[0] = mi[0] = 1;for(int i = 1;i < maxn;++i)mi[i] = 2ll*mi[i-1]%mod;inv[1] = powmod(2,mod-2);for(int i = 2;i < maxn;++i)inv[i] = inv[1]*inv[i-1]%mod;scanf("%lld%lld%lld",&n,&m,&k);for(int i = 1;i <= n;++i)scanf("%lld",&val[i]);for(int i = 1;i <= k;++i)scanf("%lld",&s[i]);for(int i = 0;i < m;++i){int a,b;scanf("%d%d",&a,&b);G[a].push_back(b);G[b].push_back(a);deg[a]++;deg[b]++;}for(int i = 1;i <= n;++i)for(int j = 0;j < G[i].size();++j)if(deg[i] > 300) heavy[G[i][j]].push_back(i),big[i] = 1;for(int i = 1;i <= k;++i){cnt[s[i]]++;if(cnt[s[i]] == 1)for(int j = 0;j < G[i].size();++j)vis[G[i][j]] = 1;}for(int i = 1;i <= n;++i){if(vis[i] && !cnt[i] && val[i] > 0)return 0*puts("-1");}for(int i = 1;i <= n;++i){val[i] = val[i]*powmod((1-inv[cnt[i]]+mod)%mod,mod-2)%mod;}for(int i = 1;i <= n;++i){if(big[i]) continue;for(int j = 0;j < G[i].size();++j)sum[G[i][j]] = (sum[G[i][j]] + val[i])%mod;}ll res = 0;for(int i = 1;i <= k;++i){int u = s[i];res = (res + sum[u])%mod;for(int j = 0;j < heavy[u].size();++j){int v = heavy[u][j];res = (res + val[v])%mod;}ll old = val[u];val[u] = old*inv[1]%mod;//val[u] = val[u]*inv[1]%mod;if(!big[u]){for(int j = 0;j < G[u].size();++j){int v = G[u][j];sum[v] = (sum[v] - old + val[u] + mod)%mod;}}   }cout<<res<<endl;return 0;
}

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

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

相关文章

P5579-[PA2015]Siano【线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P5579 题目大意 nnn个树&#xff0c;第iii个每天长高aia_iai​米。 mmm次修剪&#xff0c;第iii次在did_idi​天&#xff0c;将高度为bib_ibi​的部分修剪掉 求每次修剪掉的高度 解题思路 按照aia_iai​排序后我们知道每次修…

【结论】立体井字棋(jzoj 2124)

立体井字棋 题目大意&#xff1a; 在一个nnn的正方体中&#xff0c;由n个格子连成一条直线的方案数&#xff08;多少种可能用n个格子连成一条直线&#xff09; 样例输入 2 样例输出 28 数据范围限制 对于30%的数据&#xff0c; n<10&#xff1b; 对于100%的数据&am…

ASP.NET Core Identity 实战(3)认证过程

如果你没接触过旧版Asp.Net Mvc中的 Authorize 或者 Cookie登陆&#xff0c;那么你一定会疑惑 认证这个名词&#xff0c;这太正式了&#xff0c;这到底代表这什么&#xff1f;获取资源之前得先过两道关卡Authentication & Authorization要想了解Identity中用户登录之后&…

codeforces gym-101745 D-Stamp Stamp Stamp动态规划

题解 一道很不错的动态规划问题&#xff0c;首先这些印章一定是s的子串。 我们可以枚举s的子串然后进行check。 如何check&#xff0c;成了这道题的关键。 由于盖章的顺序不知道&#xff0c;所以我们可以使用动态规划的方法。 我们定义状态&#xff1a; dp[i][j]dp[i][j]…

【图论】【最短路】【SPFA】【USACO题库】2.4.4 Bessie Come Home回家(jzoj 1274)

Bessie Come Home回家 题目大意: 有n条路连接着一些牧场&#xff0c;每个牧场由‘a-z’&#xff08;没羊&#xff09;和‘A-Y’&#xff08;有一头羊&#xff09;&#xff0c;问哪个有羊的牧场离‘Z’最近 INPUT FORMAT 第 1 行: 整数 P(1< P<10000),表示连接牧场(谷…

nssl1470-X【并查集,素数】

正题 题目大意 将nnn个数分为222个非空的集合&#xff0c;要求两个集合内数的乘积的gcdgcdgcd为111。求方案数 解题思路 拥有相同质因子的数一定要在同一组&#xff0c;枚举质因数然后将拥有的数都用并查集合并然后用联通块数量来求即可。 codecodecode #include<cstdio&…

尝鲜.net core2.1 ——编写一个global tool

本文内容参考微软工程师Nate McMaster的博文.NET Core 2.1 Global Tools用过npm开发都知道&#xff0c;npm包都可以以全局的方式安装&#xff0c;例如安装一个http-server服务&#xff0c;可以使用npm i http-server -g来将http-server包安装到全局环境。安装完之后&#xff0c…

codeforces gym-101755 D-Transfer Window 二分图匹配、递归

题目 题目链接 题意 告诉了n名球员的交换关系&#xff0c;你现在拥有k名球员&#xff0c;你想要其他k名球员(有的在自己队里)。 输出一种交换方案。 题解 第一步、求闭包。 我们需要在原来的交换矩阵上跑可达闭包&#xff0c;即G[i][j]G[i][j]的含义是jj是否能通过i&quo…

【最短路】【Dijkstra】【图论】最小花费(jzoj 2125)

最小花费 题目大意&#xff1a; n个人&#xff0c;一些人之间可以相互转账&#xff0c;但又手续费x%,问A转给B100元至少要多少钱 样例输入 3 3 1 2 1 2 3 2 1 3 3 1 3 样例输出 103.07153164 数据范围限制 对于所有数据&#xff0c; 1 < n <2000。 解题思路…

jzoj1471-Y【bitset,dp,状压】

正题 题目大意 nnn个点mmm条边&#xff0c;边上是0/10/10/1&#xff0c;求有多少种不同的长度为ddd的路径序列 解题思路 我们将ddd分为两半&#xff0c;定义fi,j,sf_{i,j,s}fi,j,s​表示从iii出发到jjj&#xff0c;路径序列状态sss是否可行。 然后我们可以用bitsetbitsetbits…

Comet OJ-栈的数据结构题【线段树】

正题 题目链接:https://cometoj.com/contest/79/problem/E?problem_id4207 题目大意 nnn个栈&#xff0c;要求支持操作 l∼rl\sim rl∼r区间内的栈压入一个数l∼rl\sim rl∼r区间内的栈弹出一个数求第xxx个栈内第kkk个数 解题思路 对于每个询问我们其实就是要求在他之前的第…

codeforces gym-101755 I-Guess the Tree 交互题、分治、树的直径

题目 题目链接 题意 n2h−1&#xff0c;且1≤n≤1023n2h−1&#xff0c;且1≤n≤1023你可以最多询问2.5∗logn12∗n2.5∗log2n1∗n次&#xff0c;任意两点的距离&#xff0c;让你还原一颗完全二叉树。 题解 第一步、肯定要求整棵树的根节点。 由于这是一颗完全二叉树&…

【01背包】最大约数和(jzoj 2126)

最大约数和 题目大意&#xff1a; 选若干个正整数&#xff0c;和不小于S&#xff0c;使每个数的因数&#xff08;不包括本身&#xff09;之和最大 样例输入 11 样例输出 9 数据范围限制 对于30%的数据&#xff0c; S<10&#xff1b; 对于100%的数据&#xff0c; S …

微软75亿收购Github,微软以开发者为中心的初心不变

前天关于微软要收购 GitHub 的消息传出后&#xff0c;很多人都纷纷讨论&#xff0c;希望 GitHub 能够独立存在&#xff0c;不被任何大厂收购&#xff0c;可是 GitHub 也要生存啊。那又有人说&#xff1a;希望是 Google 来收购 GitHub &#xff0c;而不是微软&#xff0c;在大家…

nssl1476-联【线段树】

正题 题目大意 无限长的010101序列&#xff0c;每次进行一个操作 区间内赋值为000区间内赋值为111区间取反 求第一个000的位置 解题思路 离散化&#xff08;储存每个区间的左右端点和他们加一之后的值&#xff09;后可以用线段树储存第一个000和第一个111的位置。然后区间取…

洛谷-P3396 哈希冲突 分块

题目 题目链接 题意 给你个数列&#xff0c;编号为1…n1…n。 给出两种操作&#xff1a; 查询操作&#xff1a;查询所有编号模xx得y" role="presentation" style="position: relative;">yy的对应数字之和。修改操作&#xff1a;把编号为xx的数…

简明 ASP.NET Core 手册

编者&#xff1a;在4月份推送过这篇文章 简明 ASP.NET Core 手册 &#xff0c;今天再次推荐这篇文章&#xff0c;是因为原作者更新到了新版本1.1.0&#xff0c;改动很大&#xff0c;几乎所有章节都有很大程度的调整&#xff0c;这些调整都是根据读者的建议而做&#xff0c;而且…

【模拟】【递归】电子表格(jzoj 2127)

电子表格 题目大意&#xff1a; 有一个Excel文档&#xff0c;有4中操作&#xff1a;input输入一个格子的值&#xff0c;output输出一个格子的值&#xff0c;sum某个格子等于一块矩形中的总值&#xff08;矩形中的总值改变&#xff0c;这个格子也要改变&#xff09;&#xff0…

nssl1477-赛【对顶堆,贪心】

正题 题目大意 nnn个物品&#xff0c;有两个人&#xff0c;每个人有一些喜欢的物品。 选mmm个物品&#xff0c;至少选择kkk个第一个人喜欢的和kkk个第二个人喜欢的物品 解题思路 首先我们必定是选最小的 我们从小到大枚举选择多少两个人都喜欢的物品iii&#xff0c;然后每人选…

洛谷-P1903 数颜色 分块 bitset

题目 题目链接 题意 给你一个数列代表不同的颜色&#xff08;可以修改&#xff09;。 询问一段区间内有多少种颜色。 题解 很容易想到的就是线段树来维护bitset。 这里为了练习&#xff0c;使用分块维护bitset。 * 事实上线段树可以看成是无限分块。* 修改的时候直接暴…