题目链接:https://zhixincode.com/contest/14/problem/I?problem_id=211

样例输入 1 

3 5
2 1
1 2 1
2 1
1 2 3
2 1

样例输出 1

27
9
6

题解:

首先,比较明显地是,每进行一次操作 $1$,对于目前的卡牌分配情况的种数,其中的 $1/3$ 种是被撤掉位子的人留下,其余 $2/3$ 种是“擂主”留下。

而且,进行完一次操作 $1$ 后,“擂主”位子上分配到的卡牌,石头剪刀布的数目比依然是均等的,因此不会影响后面继续进行操作 $1$ 时的 $1/3 : 2/3$ 的情况种数的比例。

所以,最初没有撤掉过座位,每个人使得他们留下的卡牌分配种数都是 $3^n$ 种。然后一旦进行一次操作 $1$,被撤掉位子的人他的种数就变为原来的 $1/3$,擂主则变为原来的 $2/3$。

那么,一种最朴素的做法就是,保存下所有操作 $1$,对于每次操作 $2$ 查询,都遍历一遍其前面的所有操作 $1$,从 $3^n$ 一直不断地乘以 $1/3$ 或 $2/3$ 直到算出目前的答案。

例如题目的样例,第 $1$ 个人留下来的情况,可以表示成一个简单图表可以如下:

但是这样的时间复杂度是 $O(m^2)$ 的,我们要进行一定的优化。

对于一名选手,他如果经过 $a$ 次主场作战,$b$ 次客场作战,那么其对应的查询答案就是 $(\frac{2}{3})^a \cdot (\frac{1}{3})^b \cdot 3^n$。

也就是说,我们要维护每个选手的主场作战次数和客场作战的次数。

我们对于每个座位,不妨将其看做一个集合,集合内的存储的是可能坐在这个位置上的选手的编号。

那么,每次操作 $1$ 相当于合并两个集合,如果我们对每个选手 $p$ 用两个属性 $p.a$ 和 $p.b$ 分别记录其进行的主场和客场比赛数目。

那么我们可以用带权并查集来进行维护:

首先我们知道,任何一个节点,它自己外加它的所有子孙,合起来作为一个集合。我对每个节点 $v$ 都设 $\Delta a[v]$ 和 $\Delta b[v]$,表示其所统领的整个集合(也就是,该节点本身,以及其所有子孙节点,共同组成的集合),这个集合内的所有节点的主场数目都加上 $\Delta a[v]$,客场数目都加上 $\Delta b[v]$。

那么,对于并查集的合并(把一个根节点接到另一个根节点下)和查询操作(把一个节点一点点往上爬直到接到树根下为止),我们都可以比较自然的得出如何维护 $\Delta a[v]$ 和 \Delta $b[v]$,详见代码。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
#define mk(x,y) make_pair(x,y)
const ll mod=;
const int maxn=2e5+; int n,m; int par[maxn];
ll a[maxn],b[maxn];
int find(int x)
{
if(par[x]==x) return x;
int rt=find(par[x]);
if(par[x]!=rt) a[x]+=a[par[x]], b[x]+=b[par[x]];
return par[x]=rt;
} ll fpow(ll a,int n)
{
ll res=, base=a%mod;
while(n)
{
if(n&) res*=base, res%=mod;
base*=base, base%=mod;
n>>=;
}
return res%mod;
}
inline ll inv(ll a){return fpow(a,mod-);}
ll calc(int a,int b)
{
ll _1_3=inv(), _2_3=*_1_3%mod;
ll res=fpow(,n);
res*=fpow(_2_3,a), res%=mod;
res*=fpow(_1_3,b), res%=mod;
return res;
} int main()
{
ios::sync_with_stdio();
cin.tie(), cout.tie(); cin>>n>>m;
for(int i=;i<=n;i++) par[i]=i, a[i]=, b[i]=;
for(int i=,t,x,y;i<=m;i++)
{
cin>>t;
if(t==)
{
cin>>x>>y;
a[x]++, b[y]++;
a[y]-=a[x], b[y]-=b[x];
par[y]=x;
}
if(t==)
{
cin>>x;
int rt=find(x);
if(x==rt) cout<<calc(a[x],b[x])<<"\n";
else cout<<calc(a[rt]+a[x],b[rt]+b[x])<<"\n";
}
}
}

PS.可怜老师出的并查集好强,充满了教育意义QAQ。

CCPC-Wannafly Winter Camp Day3 Div1 - 石头剪刀布 - [带权并查集]的更多相关文章

  1. 石头剪刀布(2019Wannafly winter camp day3 i) 带权并查集+按秩合并 好题

    题目传送门 思路: 按照题意描述,所有y挑战x的关系最后会形成一棵树的结构,n个人的总方案数是 3n 种,假设一个人被挑战(主场作战)a次,挑战别人(客场)b次,那么这个人存活到最后的方案数就是3n* ...

  2. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  3. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  4. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  5. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  6. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

  7. 【BZOJ-4690】Never Wait For Weights 带权并查集

    4690: Never Wait for Weights Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 41[Submit][ ...

  8. hdu3038(带权并查集)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示 ...

  9. 洛谷OJ P1196 银河英雄传说(带权并查集)

    题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...

随机推荐

  1. JavaScript绑定this

    问题描述 var a = { one: 1, haha() { console.log(this.one) } } setTimeout(a.haha, 1000) 在上例中,函数haha引用了thi ...

  2. struts2:标签库图示,控制标签

    目录 一.struts2标签库图示二.控制标签1. 条件判断标签(if/elseif/else)2. 迭代标签(iterator) 2.1 遍历List 2.2 遍历Map 2.3 遍历List(Ac ...

  3. 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅

    在第一篇教程中,我们展示了如何使用start.spring.io来利用Spring Initializr创建一个具有RabbitMQ starter dependency的项目来创建spring-am ...

  4. 基于mindwave脑电波进行疲劳检测算法的设计(5)

    时隔两个多月了,前段时间在弄Socket,就没有弄这个了.现在好了,花了几天的时间,终于又完成了一小部分了.这一小节主要讲α,β,δ,θ等等波段之间的关系.废话不多说,直接给出这几天的成果. 上一次, ...

  5. 【iCore1S 双核心板_FPGA】例程七:基础逻辑门实验——逻辑门使用

    实验现象: 打开tool-->Netlist viewer-->RTL viewer可观察各个逻辑连接 核心代码: //-----------------Module_logic_gate ...

  6. HyperLogLog

    数据量一大,连统计基数也成了一个麻烦事.在使用kylin的时候,遇到对度量值进行基数统计,使用的是Hyperloglog算法,占用内存小,误差小,实乃不错的方法,但查阅网上的资料与内容,感觉未能理解的 ...

  7. Java JPA小记

    什么是JPA JPA之于ORM(持久层框架,如MyBatis.Hibernate等)正如JDBC之于数据库驱动. JDBC是Java语言定义的一套标准,规范了客户端程序访问关系数据库(如MySQL.O ...

  8. 【转帖】39个让你受益的HTML5教程

    39个让你受益的HTML5教程                    闲话少说,本文作者为大家收集了网上学习HTML5的资源,期望它们可以帮助大家更好地学习HTML5. 好人啊! 不过,作者原来说的4 ...

  9. Zookeeper系列四:Zookeeper实现分布式锁、Zookeeper实现配置中心

    一.Zookeeper实现分布式锁 分布式锁主要用于在分布式环境中保证数据的一致性. 包括跨进程.跨机器.跨网络导致共享资源不一致的问题. 1. 分布式锁的实现思路 说明: 这种实现会有一个缺点,即当 ...

  10. React Native 项目整合 CodePush 全然指南

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/y4x5M0nivSrJaY3X92c/article/details/81976844 作者 | 钱 ...