P5385 [Cnoi2019]须臾幻境(LCT+主席树,思维题)
题目
做法
考虑一条边\((u,v)\)是否\([L,R]\)中的贡献:\([L,R]\)中第一条位于\(u,v\)链的边,则减少了一个联通块
实现:\(LCT\)维护最小边,产生环则删除最小边,再替换\((\)和这题差不多\()\)
得出删除序列,建好主席树,直接查询\([L,R]\)中小于\(L\)的数量即可
Code
#include<bits/stdc++.h>
typedef int LL;
inline LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}return x*f;
}
const LL maxn=1e6+9,inf=0x3f3f3f3f;
LL n,m,q,seed;
LL ear[maxn];
namespace LCT{
struct node{
LL u,v;
}e[maxn];
LL son[maxn][2],fa[maxn],mi[maxn],mi_n[maxn],val[maxn],sta[maxn],r[maxn];
inline LL Notroot(LL x){
return son[fa[x]][0]==x || son[fa[x]][1]==x;
}
inline void Update(LL x){
LL lt(son[x][0]),rt(son[x][1]);
mi[x]=std::min(mi[lt],mi[rt]);
if(mi[x]==mi[lt]){
mi_n[x]=mi_n[lt];
}else{
mi_n[x]=mi_n[rt];
}
if(val[x]<=mi[x]){
mi[x]=val[x]; mi_n[x]=x;
}
}
inline void Pushr(LL x){
std::swap(son[x][0],son[x][1]); r[x]^=1;
}
inline void Pushdown(LL x){
if(r[x]){
if(son[x][0]) Pushr(son[x][0]);
if(son[x][1]) Pushr(son[x][1]);
r[x]=0;
}
}
inline void Rotate(LL x){
LL y(fa[x]),z(fa[y]),lz(son[y][1]==x);
if(Notroot(y)) son[z][son[z][1]==y]=x;
son[y][lz]=son[x][lz^1]; fa[son[y][lz]]=y;
son[x][lz^1]=y; fa[y]=x;fa[x]=z;
Update(y); Update(x);
}
inline void Splay(LL x){
LL y(x),tot(0);
sta[++tot]=y;
while(Notroot(y)) sta[++tot]=y=fa[y];
while(tot) Pushdown(sta[tot--]);
while(Notroot(x)){
y=fa[x];
if(Notroot(y)){
LL z(fa[y]);
if((son[y][0]==x)^(son[z][0]==y)) Rotate(x); else Rotate(y);
}Rotate(x);
}
}
inline void Access(LL x){
for(LL y=0;x;y=x,x=fa[x]){
Splay(x); son[x][1]=y; Update(x);
}
}
inline void Makeroot(LL x){
Access(x); Splay(x); Pushr(x);
}
inline void Split(LL x,LL y){
Makeroot(x); Access(y); Splay(y);
}
inline LL Query(LL x,LL y){
Split(x,y); return mi_n[y];
}
inline LL Find(LL x){
Access(x); Splay(x);
while(son[x][0]){
Pushdown(x); x=son[x][0];
}Splay(x);
return x;
}
inline void Cut(LL x,LL y){
Split(x,y); son[y][0]=fa[x]=0; Update(y);//这里也可不更新,因为在查询时整条链都会更新
}
inline void Link(LL x,LL y){
Makeroot(x); fa[x]=y;
}
inline void Solve(){
for(LL i=0;i<=n;++i) val[i]=mi[i]=inf,mi_n[i]=i;
LL tot=n;
for(LL i=1;i<=m;++i){
LL u(Read()),v(Read());
e[i]=(node){u,v};
if(u==v){
ear[i]=i; continue;
}else if(Find(u)==Find(v)){
LL t(Query(u,v)),x(val[t]); ear[i]=x;
Cut(e[x].u,t); Cut(e[x].v,t);
}
++tot; mi[tot]=val[tot]=i; mi_n[tot]=tot;
Link(u,tot); Link(v,tot);
}
}
}
namespace Sgt{
LL nod;
LL size[maxn*20],son[maxn*20][2],root[maxn];
void Update(LL pre,LL &now,LL l,LL r,LL v){
now=++nod; size[now]=size[pre]+1;
if(l==r) return;
LL mid(l+r>>1);
if(v<=mid){
Update(son[pre][0],son[now][0],l,mid,v);
son[now][1]=son[pre][1];
}else{
Update(son[pre][1],son[now][1],mid+1,r,v);
son[now][0]=son[pre][0];
}
}
LL Query(LL pre,LL now,LL l,LL r,LL v){
if(l==r) return size[now]-size[pre];
LL mid(l+r>>1);
if(mid<v) return Query(son[pre][1],son[now][1],mid+1,r,v)+size[son[now][0]]-size[son[pre][0]];
else return Query(son[pre][0],son[now][0],l,mid,v);
}
inline void Solve(){
for(LL i=1;i<=m;++i) Update(root[i-1],root[i],0,m,ear[i]);
LL lst(0);
while(q--){
LL l(Read()),r(Read());
if(seed>0)
l=1ll*(l+1ll*seed*lst%m)%m+1,
r=1ll*(r+1ll*seed*lst%m)%m+1;
if(l>r) std::swap(l,r);
printf("%d\n",lst=n-Query(root[l-1],root[r],0,m,l-1));
}
}
}
int main(){
n=Read(); m=Read(); q=Read(); seed=Read();
LCT::Solve();
Sgt::Solve();
return 0;
}
P5385 [Cnoi2019]须臾幻境(LCT+主席树,思维题)的更多相关文章
- 题解 洛谷 P5385 【[Cnoi2019]须臾幻境】
首先我们知道 \(n\) 个点的树有 \(n-1\) 条边,因此对于森林来说,其点数减边数即为树的个数.那么对于普通的图,求出其任意一个生成树森林,森林中树的个数即为原图中连通块的个数,也就是点数减边 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ...
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)
题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...
- bzoj3514(LCT+主席树)
题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- BZOJ3514:GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
随机推荐
- 禁止迅雷极速版被强制升级为迅雷x
PS:迅雷极速版( ThunderSpeed1.0.34.360 )下载地址: https://pan.baidu.com/s/1wuBOpNbim5jBru03AfSAVg 按照下面的这个路径去找. ...
- HttpClinet工具类
一.URL调用 忽略https证书 1.调用 InputStream in = null; try { URL url = new URL( "url地址" ); IgnoreSS ...
- Solr+ik分词支持特殊符号分词
在工具类(CharacterUtil.java)里,找到方法 identifyCharType,加入以下代码: } else if (ub == Character.UnicodeBlock.GREE ...
- redis 异常 MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk
MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. 解决方 ...
- 【hadoop】MapReduce分布式计算框架原理
PS:实操部分就省略了哈,准备最近好好看下理论这块,其实我是比较懒得哈!!! <?>MapReduce的概述 MapReduce是一种计算模型,进行大数据量的离线计算.MapReduce实 ...
- python Linux 环境 (版本隔离工具)
python Linux 环境 (版本隔离工具) 首先新建用户,养成良好习惯useradd python 1.安装pyenv GitHub官网:https://github.com/pyenv/pye ...
- Linux环境变量$PATH
3. 使用env命令显示所有的环境变量 # env HOSTNAME=redbooks.safe.org PVM_RSH=/usr/bin/rsh Shell=/bin/bash TERM=xterm ...
- Mybatis中传递多个参数的方法总结
一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...
- c# Regex类
- 关于视频解码总结--JavaCV
关于视频解码的所收集资料进行总结 前言:内容不全,但有一定参考性! 关于java后台视频解码 进行js将视频每秒或更低裁截传输,后台使用最优方案(自己感觉): JavaCV(点击进入) 缺点:整合工具 ...