[CSP-S模拟测试]:地理课(并查集+线段树分治)
题目传送门(内部题146)
输入格式
从$geography.in$读入数据。
第一行两个数$n,m$,表示有$n$个点,$m$个时刻。接下来$m$行每行三个数,要么是$1\ u\ v$,要么是$2\ u\ v$,分别表示添加一条无向边和删除一条无向边。
输出格式
输出答案到$geography.out$。
共$m$行,每行一个数表示连通块大小乘积$\mod 1,000,000,007$。
样例
样例输入:
5 6
1 1 3
1 2 3
1 1 2
1 4 5
1 3 4
2 3 4
样例输出:
2
3
3
6
5
6
数据范围与提示
样例解释:






上面是每个时刻操作后的图。乘积分别为:
$$2\times 1\times 1\times 1=2,3\times 1\times 1=3,3\times 1\times 1=3,3\times 2=6,5,3\times 2=6$$
数据范围:
$subtask1:30pts,n\leqslant 1,000,m\leqslant 2,000$。
$subtask2:20pts$,满足没有删除操作。
$subtask3:50pts,n,m\leqslant 100,000$。保证没有重边自环,不会删除不存在的边。
题解
这好像是一道模板题。
具体思路就是将问题离线,然后按时间建一棵线段树,在线段树上分治,递归的时候不断的将边加入并查集,到底层的时候统计答案即可。
需要注意的是还要支持回退,在递归下去的时候记录一下当前修改了哪些点的$father$或者权值,返回的时候直接改回来即可。
时间复杂度:$\Theta(\omega\times n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
const int mod=1000000007;
struct rec{int nxt,to;}e[200001];
int head[100001],cnt;
map<pair<int,int>,int>mp;
int n,m;
int f[100001],sz[100001],question[100001];
pair<int,int>wzc[100001];
vector<int>tr[400001];
vector<pair<pair<int,int>,pair<int,int>>>vec[400001];
long long qpow(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)res=res*x%mod;
x=x*x%mod;y>>=1;
}
return res;
}
int find(int x){return x==f[x]?x:find(f[x]);}
void change(int x,int l,int r,int L,int R,int w)
{
if(r<L||R<l)return;
if(L<=l&&r<=R){tr[x].push_back(w);return;}
int mid=(l+r)>>1;
change(L(x),l,mid,L,R,w);
change(R(x),mid+1,r,L,R,w);
}
void ask(int x,int l,int r,int k)
{
for(int i=0;i<tr[x].size();i++)
{
int fx=find(wzc[tr[x][i]].first);
int fy=find(wzc[tr[x][i]].second);
if(fx==fy)continue;
if(sz[fx]<sz[fy])fx^=fy^=fx^=fy;
vec[x].push_back(make_pair(make_pair(fx,sz[fx]),make_pair(fy,f[fy])));
k=1LL*k*qpow(sz[fx],mod-2)%mod*qpow(sz[fy],mod-2)%mod;
f[fy]=fx;
sz[fx]+=sz[fy];
k=1LL*k*sz[fx]%mod;
}
if(l==r)printf("%d\n",k);
else
{
int mid=(l+r)>>1;
ask(L(x),l,mid,k);
ask(R(x),mid+1,r,k);
}
for(int i=vec[x].size()-1;~i;i--)
{
f[vec[x][i].second.first]=vec[x][i].second.second;
sz[vec[x][i].first.first]=vec[x][i].first.second;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){f[i]=i;sz[i]=1;}
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d%d",&x,&x,&y);
if(x>y)x^=y^=x^=y;
int now=mp[make_pair(x,y)];
if(!now){mp[make_pair(x,y)]=++cnt;question[cnt]=i;wzc[cnt]=make_pair(x,y);}
else
{
if(question[now]){change(1,1,m,question[now],i-1,now);question[now]=0;}
else question[now]=i;
}
}
for(int i=1;i<=cnt;i++)if(question[i])change(1,1,m,question[i],m,i);
ask(1,1,m,1);
return 0;
}
rp++
[CSP-S模拟测试]:地理课(并查集+线段树分治)的更多相关文章
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
- 【BZOJ4025】二分图(可撤销并查集+线段树分治)
题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...
- 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic
本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
- 并查集&线段树&树状数组&排序二叉树
超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...
- BZOJ 3910 并查集+线段树合并
思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...
- [CSP-S模拟测试]:影子(并查集+LCA)
题目描述 一个人有很多的影子,新的旧的,他们不断消失重来.学者的影子在他苍白色的精神图景里成为了$n$个黑色的点,他们伸长的触手交叉形成了一颗黑色的树.假使每个影子点拥有一个权值$d_i$,黑色的树边 ...
- csp-s模拟测试55(9.29)联「线段树」·赛「??」题「神仙DP」
T1 联 考试两个小时终于调过了,话说一个傻逼错最后还是静态查出错的..... 大概维护两个懒标记,一个区间覆盖,一个区间异或,然后保证每个区间只会存在一种懒标记. 然后维护区间0的个数,查询时查询那 ...
- BZOJ2733 [HNOI2012]永无乡(并查集+线段树合并)
题目大意: 在$n$个带权点上维护两个操作: 1)在点$u,v$间连一条边: 2)询问点$u$所在联通块中权值第$k$小的点的编号,若该联通块中的点的数目小于$k$,则输出$-1$: 传送门 上周的模 ...
随机推荐
- C#实现鼠标滚筒缩放界面的效果
elementCanvas继承UserControl 声明属性: #region 缩放属性添加 float ratio = 1.0f; public float Ratio { set { ratio ...
- 如何调试Python程序 通过IDLE
在python3.3环境下 1.写一个简单地Python源文件,比如test.py,内容如下: import sys, osdef test(arg1, arg2): print "begi ...
- 关于学习电信nb-iot的小结
关于这几天对nb-iot的学习的总结和遇到的坑 初步学习nb-iot,了解到了nb-iot对于传感器数据传输功能的强大: 废话不多说,对于nb-iot我们选择的有人的模块,选择B5频段也就是电信的nb ...
- VMwarevSphere Client 链接 vCenter Server中的主机,开启虚拟机提示:在主机当前连接状况下不允许执行该操作
VMwarevSphere Client 链接 vCenter Server中的主机,开启虚拟机提示:在主机当前连接状况下不允许执行该操作很多原因都可以导致该问题出现,例如 vCenter Serve ...
- deep_learning_Function_ Matplotlib 3D 绘图函数 plot_surface 的 rstride 和 cstride 参数
今晚开始接触 Matplotlib 的 3D 绘图函数 plot_surface,真的非常强大,图片质量可以达到出版级别,而且 3D 图像可以旋转 ,可以从不同角度来看某个 3D 立体图,但是我发现各 ...
- 在Linux中,当需要从磁盘读取块时,进程状态会发生什么变化?被封锁了吗?如果是这样,如何选择另一个流程来执行?
当某个进程需要从磁盘中获取数据时,它实际上会停止在CPU上运行以让其他进程运行,因为该操作可能需要很长时间才能完成-至少需要5ms的磁盘寻道时间,而5ms就是1000万从程序的角度来看,CPU周期是永 ...
- kafka api的基本使用
kafka API kafka Consumer提供两套Java API:高级Consumer API.和低级Consumer API. 高级Consumer API 优点: 高级API写起来简单,易 ...
- AWK程序设计语言
一. AWK入门指南 Awk是一种便于使用且表达能力强的程序设计语言,可应用于各种计算和数据处理任务.本章是个入门指南,让你能够尽快地开始编写你自己的程序.第二章将描述整个语言,而剩下的章节将向你展示 ...
- 用cubase制作消音伴奏
- BZOJ 1003 最短路dp
物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因 ...