毒瘤染色

题目链接:YBT2022寒假Day3 C

题目大意

要你在线实现一个操作:
一开始有 n 个点,没有边,然后操作会给你一条边。
如果保证加了之后这个图还是沙漠就加上。
然后每次加完边之后问你一开始所有点都是白色做 k 次每次随机选一个点(可能白色)的点把它变成白色,然后问你分别保留黑白点是的连通块个数的期望值。
(有部分分只用求保留白点的)

思路

考虑分别处理加边的操作和询问。

那沙漠一般来讲要么就用圆方树,要么就直接拆链搞,那这个应该是要前面的那个。
你考虑你其实就是要看两个点之间是否连通,这个好搞,和两个点的路径点是否有环,而且会出现新的环。

那我们不如用 LCT 来弄,记录方点圆点个数(方点是一个环的代表点,圆点就是普通点)
然后如果路径中有方点就是有环,就不能加边。(这里没有必要圆方点交错的那种)

然后考虑询问,考虑连通块如何表示:
在是普通的没有环的图上,它可以表示成点数 - 边数。
那现在有环,但是是沙漠,可以表示成点数 - 边数 + 环数。

那由于每次选的概率每个点相同,每个点是黑色或者白色的概率是相同的。
所以边的概率就是它连接的两个点都存在的概率,环存在的概率就是环上所有点都存在的概率。

那我们设 w x w_x wx​ 为选 x x x 个点,都是白点的概率, b x b_x bx​ 为都是黑点的概率。然后设 f x = w x + ω b x f_x=w_x+\omega b_x fx​=wx​+ωbx​。
然后答案就是 n ∗ f 1 − m ∗ f 2 + ∑ f s z i n*f_1-m*f_2+\sum f_{sz_i} n∗f1​−m∗f2​+∑fszi​​( s z i sz_i szi​ 为每个环的大小)。

然后你在连边的时候更新 m , s z i m,sz_i m,szi​ 即可。(一个是加边了就更新,一个是出现了新的环就更新)
然后接着问题就是 w x , b x w_x,b_x wx​,bx​ 怎么求。

w x w_x wx​ 很好求,就是不被选到: ( n − x n ) k (\dfrac{n-x}{n})^k (nn−x​)k。
那接着就是求 b x b_x bx​,考虑容斥求:
b x = ∑ i = 0 x ( − 1 ) i ( n − i n ) k C x i b_x=\sum\limits_{i=0}^x(-1)^i(\dfrac{n-i}{n})^kC_x^i bx​=i=0∑x​(−1)i(nn−i​)kCxi​

然后就好了。

代码

#include<cstdio>
#include<vector>
#include<algorithm>
#define ll long long
#define mo 998244353using namespace std;ll n, q, k, w, m;
ll x, y, lst, tot;
vector <ll> tmp;ll b1, b2, invn, f2;
ll jc[100001], inv[100001];
ll b[100001], ans;ll ksm(ll x, ll y) {ll re = 1;while (y) {if (y & 1) re = re * x % mo;x = x * x % mo;y >>= 1;}return re;
}ll C(ll n, ll m) {if (n < m || m < 0) return 0;return jc[n] * inv[m] % mo * inv[n - m] % mo;
}struct LCT {ll ls[400001], rs[400001], cir[400001];ll sz[400001], cirsz[400001], fa[400001];bool lzyc[400001];void Init() {for (ll i = 1; i <= n; i++) sz[i] = cir[i] = cirsz[i] = 1;}bool nrt(ll x) {return ls[fa[x]] == x || rs[fa[x]] == x;}bool lrs(ll x) {return ls[fa[x]] == x;}void up(ll x) {sz[x] = sz[ls[x]] + sz[rs[x]] + 1;cirsz[x] = cirsz[ls[x]] + cirsz[rs[x]] + cir[x];}void downc(ll now) {lzyc[now] ^= 1; swap(ls[now], rs[now]);}void down(ll now) {if (lzyc[now]) {if (ls[now]) downc(ls[now]);if (rs[now]) downc(rs[now]);lzyc[now] = 0;}}void down_line(ll now) {if (nrt(now)) down_line(fa[now]);down(now);}void rotate(ll x) {ll y = fa[x], z = fa[y];ll b = lrs(x) ? rs[x] : ls[x];if (z && nrt(y)) (lrs(y) ? ls[z] : rs[z]) = x;if (lrs(x)) rs[x] = y, ls[y] = b;else ls[x] = y, rs[y] = b;fa[x] = z; fa[y] = x;if (b) fa[b] = y;up(y);}void Splay(ll x) {down_line(x);while (nrt(x)) {if (nrt(fa[x])) {if (lrs(x) == lrs(fa[x])) rotate(fa[x]);else rotate(x);}rotate(x);}up(x);}void access(ll x) {ll lst = 0;for (; x; x = fa[x]) {Splay(x);rs[x] = lst; up(x);lst = x;}}void make_root(ll x) {access(x);Splay(x);downc(x);}ll find_root(ll now) {access(now);Splay(now);down(now);while (ls[now]) {now = ls[now]; down(now);}return now;}ll select(ll x, ll y) {make_root(x);access(y);Splay(y);return y;}bool link(ll x, ll y) {if (find_root(x) == find_root(y)) return 0;make_root(x);fa[x] = y;return 1;}void get_all(ll now) {tmp.push_back(now);if (ls[now]) get_all(ls[now]);if (rs[now]) get_all(rs[now]);}
}T;ll get_B(ll x) {ll re = 0, di = 1;for (ll i = 0; i <= x; i++) {(re += di * C(x, i) % mo * ksm((n - i) * invn % mo, k) % mo) %= mo;di = mo - di;}return re;
}ll W(ll x) {return ksm((n - x) * invn % mo, k);
}int main() {//  freopen("graph.in", "r", stdin);
//  freopen("graph.out", "w", stdout);scanf("%lld %lld %lld %lld", &n, &q, &k, &w); invn = ksm(n, mo - 2); tot = n;T.Init();jc[0] = 1; for (ll i = 1; i <= n; i++) jc[i] = jc[i - 1] * i % mo;inv[0] = inv[1] = 1; for (ll i = 2; i <= n; i++) inv[i] = inv[mo % i] * (mo - mo / i) % mo;for (ll i = 1; i <= n; i++) inv[i] = inv[i - 1] * inv[i] % mo;b1 = get_B(1); b2 = get_B(2);ans = 1ll * n * (W(1) + w * b1) % mo;f2 = (W(2) + w * b2) % mo;while (q--) {scanf("%lld %lld", &x, &y); x ^= lst; y ^= lst;if (x == y) {printf("%lld\n", lst); continue;}if (!T.link(x, y)) {ll now = T.select(x, y), sz = T.sz[now];if (T.sz[now] == T.cirsz[now]) {ans = (ans - f2 + mo) % mo;T.sz[++tot] = 1;tmp.clear(); T.get_all(now);for (ll i = 0; i < sz; i++) {T.fa[tmp[i]] = T.ls[tmp[i]] = T.rs[tmp[i]] = 0; T.sz[tmp[i]] = T.cir[tmp[i]] = T.cirsz[tmp[i]] = 1;T.link(tmp[i], tot);}ans = (ans + W(sz)) % mo;if (w) ans = (ans + get_B(sz)) % mo;}}else ans = (ans - f2 + mo) % mo;lst = ans;printf("%lld\n", lst);}return 0;
}

【YBT2022寒假Day3 C】毒瘤染色(LCT)(圆方树)(容斥)相关推荐

  1. [学习笔记]圆方树广义圆方树

    引入 偶尔,我们会遇到一些要在无向图/仙人掌上做的问题,这些问题如果在树上就会比较方便,那么我们就开始考虑能不能把原图等效成一棵树,然后就可以方便地乱搞了? 圆方树就是一种将无向图/仙人掌变成树的数据 ...

  2. 点双联通分量,圆方树和广义圆方树

    点双联通分量 边双联通分量想必看这篇博客的同学就会,并且边双联通分量理解和打起来比较简单,就不再赘述了. 点双联通分量,类比边双的定义,它是原图的极大无向子图,满足删去子图中任意一个节点以及与其相邻的 ...

  3. [APIO2018] Duathlon 铁人两项 圆方树,DP

    [APIO2018] Duathlon 铁人两项 LG传送门 圆方树+简单DP. 不会圆方树的话可以看看我的另一篇文章. 考虑暴力怎么写,枚举两个点,答案加上两个点之间的点的个数. 看到题面中的一句话 ...

  4. LOJ.2587.[APIO2018]铁人两项Duathlon(圆方树)

    题目链接 LOJ 洛谷P4630 先对这张图建圆方树. 对于S->T这条(些)路径,其对答案的贡献为可能经过的所有点数,那么我们把方点权值设为联通分量的大小,可以直接去求树上路径权值和. 因为两 ...

  5. [APIO2018]铁人两项——圆方树+树形DP

    题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...

  6. 【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)

    题目传送门:loj bzoj 题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方.我们观察一下方程,就可以发现自由元数量=边 ...

  7. 洛谷P4630 [APIO2018] Duathlon 铁人两项 【圆方树】

    题目链接 洛谷P4630 题解 看了一下部分分,觉得树的部分很可做,就相当于求一个点对路径长之和的东西,考虑一下能不能转化到一般图来? 一般图要转为树,就使用圆方树呗 思考一下发现,两点之间经过的点双 ...

  8. [BZOJ2125]最短路(圆方树DP)

    题意:仙人掌图最短路. 算法:圆方树DP,$O(n\log n+Q\log n)$ 首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在 ...

  9. 【CF487E】Tourists【圆方树】【树链剖分】【multiset】

    题意:给一张 nnn 点 mmm 边的连通无向图,点帯权,qqq 次操作: 修改一个点的权值. 询问两点间所有简单路的最小权值的最小值. n,m,q≤105n,m,q\leq 10^5n,m,q≤10 ...

最新文章

  1. 使用Spring+CXF开发WebService
  2. 使用WinCrypt进行简单的对称加密实例
  3. java象棋人机代码_中国象棋人机对弈Java版源码
  4. SQLserver分页 高效率
  5. java data是什么文件_如何用java实现 读取一个data类型文件 并显示出来(随便选择一种类型txt或者word)...
  6. JavaScript入门(part3)--变量
  7. pdo mysql 和 mysqli_PHP中MySQL、MySQLi和PDO的用法和区别
  8. JEECG_3.7 新版本视频正式发布
  9. 2020年需要牢记的10个深度学习Best Practices
  10. 小汤学编程之JAVA经典例题——嵌套集合
  11. java获取新insert数据自增id_java获取新insert数据自增id的实现方法
  12. hbase 使用lzo_带你快速上手HBase | HBase列族优化
  13. 如何使用EasyRecovery巧妙恢复被误删的办公文档?
  14. 计算机组成原理核心总结
  15. SaaS 真实的案例, DRP
  16. html的视频字幕制作步骤,十大字幕制作软件
  17. Fluent Python读后感
  18. 测序深度和覆盖度(Sequencing depth and coverage)
  19. 新浪微博回调地址redirect_url(授权回调页)的设置格式
  20. 论文笔记:NAOMI: Non-Autoregressive MultiresolutionSequence Imputation

热门文章

  1. 四年巨亏49亿,第四范式四闯IPO
  2. Elasticsearch基础15——Elasticsearch集群健康管理
  3. 数字证书在WEB应用中登录
  4. 《Windows办公指南》msiexec.exe工具详解
  5. JAVA数组实现商品的进销存
  6. 烟台初中计算机会考,烟台初中生迎来会考科目将折算计入中考总分
  7. 艾永亮:把“卖酱油”做到极致,海天味业到底是怎么做到的?
  8. pair java_介绍java中Pair
  9. 关于TensorFlow-gpu出现nan原因
  10. 与“云”共舞,联想凌拓的新科技与新突破