题意

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

题解

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

我们现在需要一个O(nn‾√)O(nn)O(n\sqrt{n})的算法。

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

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

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

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

这道题还没有做完

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

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

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

我们设顶点vvv,初始权值为val[v]" role="presentation" style="position: relative;">val[v]val[v]val[v],在第一轮中的贡献为x1x1x_1,那么肯定有x1=p∗val[v]x1=p∗val[v]x_1 = p*val[v],其中p代表一个比例系数。

在第一轮以后,vvv的权值变成了val[v]∗12cnt[v]" role="presentation" style="position: relative;">val[v]∗12cnt[v]val[v]∗12cnt[v]val[v]*\frac{1}{2^{cnt[v]}},其中cnt[v]cnt[v]cnt[v]表示的是这个vvv点在循环节中出现的次数。

第二轮中v" role="presentation" style="position: relative;">vvv对答案的贡献是x2x2x_2,那么x2=p∗val[v]∗12cnt[v]x2=p∗val[v]∗12cnt[v]x_2 = p*val[v]*\frac{1}{2^{cnt[v]}}

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

sumx=p∗val[v]1−2−cnt[v]" role="presentation" style="position: relative;">sumx=p∗val[v]1−2−cnt[v]sumx=p∗val[v]1−2−cnt[v]sum_x = p*\frac{val[v]}{1-2^{-cnt[v]}}

关键点来了!!!
注意看sumxsumxsum_x与x1x1x_1的形式关系,发现就相当于用val[v]1−2−cnt[v]val[v]1−2−cnt[v]\frac{val[v]}{1-2^{-cnt[v]}}替换了val[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;
}

codeforces gym-101745 C-Infinite Graph Game 分块相关推荐

  1. Codeforces Gym 101173 CERC 16 D BZOJ 4790 Dancing Disks

    Codeforces Gym 101173 CERC 16 D & BZOJ 4790 Dancing Disks 强烈安利这道构造题目,非常有意思. 这里用到的思想是归并排序! 多路归并排序 ...

  2. Codeforces Gym 101086 M ACPC Headquarters : AASTMT (Stairway to Heaven)

    Codeforces Gym 101086 M ACPC Headquarters : AASTMT (Stairway to Heaven) 题目来源: Codeforces 题意: 给出一些比赛, ...

  3. [Codeforces Gym 101651/100725B] Banal Tickets

    Codeforces Gym 100725 题解: 先分两种情况, 积为000与积非0" role="presentation" style="position ...

  4. Codeforces Global Round 4-D. Prime Graph(伯特兰-切比雪夫定理)

    题目:Codeforces Global Round 4-D. Prime Graph 题意:给出n(顶点的个数),要求所得图满足: 1.无平行边和自环 2.边的总数是个质数 3.每个点的度(也就是点 ...

  5. Codeforces Gym 100513G G. FacePalm Accounting 暴力

    G. FacePalm Accounting Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513 ...

  6. Codeforces Gym 100269 Dwarf Tower (最短路)

    题目连接: http://codeforces.com/gym/100269/attachments Description Little Vasya is playing a new game na ...

  7. Codeforces Gym 100676G Training Camp 状压dp

    http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修 ...

  8. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...

  9. Codeforces Gym 100342J Problem J. Triatrip 求三元环的数量 bitset

    Problem J. Triatrip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

最新文章

  1. mockito_使用FizzBu​​zz和Mockito进行单元测试
  2. 【Android 命令行工具】Android 命令行工具简介 ( 官方文档 | SDK 命令行工具 | SDK 构建工具 | SDK 平台工具 | 模拟器工具 | Jetifier 工具 )
  3. BBAug: PyTorch的物体检测包
  4. 移动计算云分布式数据缓存服务,实现快速可靠的跨区域多活复制
  5. DIP、IoC、DI笔记整理
  6. KmdKit4D 0.01正式版发布了(0.02版已放出)
  7. 用傅里叶分析得到频域信息 MATLAB,信号频谱分析
  8. 良心国产 PDF 软件!永久免费!不流氓
  9. 提取Flash芯片信息
  10. 魔兽代理又起风云:网易暴雪腾讯的利益博弈
  11. P61-前端基础HTML-表单入门介绍
  12. 使用键盘操作将桌面计算机图标隐藏,如何创建键盘快捷方式来显示或隐藏桌面图标 | MOS86...
  13. 华为交换机5720常用命令
  14. 日志收集系统Flume笔记(基础版)
  15. 用户体验 | 深耕用户体验筑造银行竞争的护城河
  16. mysql存储图片node_Node.js教程 阿里云mysql如何支持存储emoji表情
  17. 中外企业文化杂志中外企业文化杂志社中外企业文化编辑部2022年第5期目录
  18. 【原创】Syncthing搭建自己的中继服务和发现服务
  19. linux权限管理ppt,Linux用户和权限管理.ppt
  20. 院校毕业论文答辩PPT模板

热门文章

  1. python回到本次循环开头_Python中,当一个while循环判断为false,结束这个循环的时候,怎么进入到下一个循环中?...
  2. git revert 后再次merge_git如何回滚错误合并的分支
  3. leetcode24. 两两交换链表中的节点(思路+解析)
  4. pip 设置超时时间_Python pip使用超时问题解决方案
  5. [SpringSecurity]web权限方案_用户授权_自定义403页面
  6. 2019年第十届蓝桥杯国赛B组试题D-求值-枚举
  7. 洛谷 P1706 P1036 -小试牛刀
  8. [蓝桥杯]字母组串-递归
  9. C++map容器-插入和删除
  10. Ubuntu failed to fetch ... hash sum mismatch