题意很简单:给n个条边 m条边  每一次给一个询问  l,r    问区间l~r的边构成的图的联通块个数

因为是不断加边 所以我们的lct肯定是维护边的    然后我们思考边和联通块的关系   一开始整个图是n个孤立的点   联通块的数目为n   当我们加入第一条边的时候  联通块数目-1   规律大概是  联通块数=n-边数   但是在构成环的时候就不成立了   例如  图中有 u,v 这样的一条链  u~v的点都是属于一个联通块   那么我如果加入一条边  使得u连上v  那么对联通块的减少是没有贡献的  (u到v的点仍然属于一个联通块 并且没有新的点加入)

由于这是一个区间问题 我们很容易想到一个算法  维护最大时间生成树  一条边对联通块的数目减少有贡献 当前仅当 时间比它小的并且与它构成环的最大时间边的时间严格小于L(区间左端点) 这里的时间其实就是边的序号 对于每条边 和它满足上面关系的边的序号 我们记为lb[i]

那么我们的算法已经初具规模了   每一条的时间就是序号  我们从1~m动态的加边 维护最大时间生成树

如果一条边加入的时候 没有构成环  那么 lb[i]=0  也就是说它肯定有贡献

如果一条边加入的时候 构成了一个环  我们删去环中间时间最小的边  并且令 lb[i]=该边的序号

注意两个问题:

重边:上述算法依然成立

自环:对联通块完全没有贡献 令lb[i]=m+1

那么 对于每个询问我们要求的就是     其中 lb[i]<l 是一个布尔表达式 如果成立的话 我们就记为1   因为是在线询问 显然我们需要用主席树来进行二维数点即:    

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
#define R register int
#define I inline void
#define lc c[x][0]
#define rc c[x][1]
int lb[N];
inline int in(){R x=0;char c=0;while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x;
}
struct edge{int u,v;
}e[N];
struct LCT{int mi[N],st[N],r[N],f[N],c[N][2],val[N];inline bool nroot(R x){return c[f[x]][0]==x||c[f[x]][1]==x;}I pushup(R x){mi[x]=val[x];if(lc) mi[x]=min(mi[lc],mi[x]);if(rc) mi[x]=min(mi[rc],mi[x]);}I pushr(R x){r[x]^=1;swap(lc,rc);}I pushdown(int x){if(r[x]){if(lc) pushr(lc); if(rc) pushr(rc);r[x]=0;}}I rotate(R x){R y=f[x],z=f[y],k=c[y][1]==x,w=c[x][k^1];if(nroot(y)) c[z][c[z][1]==y]=x; c[x][k^1]=y;c[y][k]=w;if(w) f[w]=y; f[y]=x;f[x]=z;pushup(y);}I splay(R x){R y=x,z=0;st[++z]=y;while(nroot(y)) st[++z]=y=f[y];while(z) pushdown(st[z--]);while(nroot(x)){y=f[x],z=f[y];if(nroot(y))rotate((c[y][1]==x)^(c[z][1]==y)?x:y);rotate(x);}pushup(x);}I access(R x){for(R y=0;x;x=f[y=x])splay(x),rc=y,pushup(x);}I makeroot(R x){access(x);splay(x);pushr(x);}I split(R x,R y){makeroot(x);access(y);splay(y);}inline int findroot(R x){access(x);splay(x);while(lc) pushdown(x),x=lc;splay(x);return x;}I link(R x,R y){makeroot(x);f[x]=y;}I cut(R x,R y){split(x,y);f[x]=c[y][0]=0;pushup(y);}inline bool judge(R x,R y){makeroot(x);if(findroot(y)==x) return true;return false;}
}T;
struct presidenttree{int sum[N*30],tot,ls[N*30],rs[N*30],rt[N];void update(R &o,R l,R r,R pos){sum[++tot]=sum[o]+1;ls[tot]=ls[o];rs[tot]=rs[o];o=tot;if(l==r) return;R mid = l+r>>1;if(pos<=mid) update(ls[o],l,mid,pos);else update(rs[o],mid+1,r,pos);}int query(R ql,R qr,R l,R r,R qL,R qR){if(qL<=l&&qR>=r) return sum[qr]-sum[ql];R mid = l+r>>1,ans = 0;if(qL<=mid) ans+=query(ls[ql],ls[qr],l,mid,qL,qR);if(qR>mid) ans+=query(rs[ql],rs[qr],mid+1,r,qL,qR);return ans;}
}P;
int main(){R n,m,q,t;n=in(),m=in(),q=in(),t=in();for(R i = 1; i <= m; i++)e[i].u=in(),e[i].v=in();for(R i = 1; i <= n; i++) T.val[i]=T.mi[i]=1e9;for(R i = 1; i <= m; i++) T.val[i+n]=T.mi[i+n]=i;for(R i = 1; i <= m; i++){R u=e[i].u,v=e[i].v;if(u==v){lb[i]=m+1;continue; }if(T.judge(u,v)){T.split(u,v);lb[i]=T.mi[v];T.cut(e[lb[i]].u,lb[i]+n);T.cut(e[lb[i]].v,lb[i]+n);}T.link(u,i+n);T.link(v,i+n);}for(int i = 1; i <= m; i++){P.rt[i]=P.rt[i-1];P.update(P.rt[i],0,m+1,lb[i]);}R lasans=0;for(R i = 1; i <= q; i++){R l,r;l=in(),r=in();if(t==1){l=(l+t*lasans)%m+1;r=(r+t*lasans)%m+1;     }if(l>r) swap(l,r);int pans=0;/*for(int i = l; i <= r; i++)if(lb[i]<=l-1) pans++;*/printf("%d\n",lasans=(n-P.query(P.rt[l-1],P.rt[r],0,m+1,0,l-1)));}return 0;
} 

P5385 [Cnoi2019]须臾幻境 LCT+主席树 维护区间联通块个数相关推荐

  1. hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)

    题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...

  2. [Cnoi2019]须臾幻境(LCT维护最大生成树+主席树/分块)

    文章目录 title solution code title solution 一棵nnn个点的树有n−1n-1n−1条边. 一般的,对于森林而言则有点数-边数=树的个数 那么我们将无向图随便生成一个 ...

  3. 【洛谷P5385】须臾幻境/【BZOJ3514】Codechef MARCH14 GERALD07加强版【LCT】【主席树】

    题意:有nnn个点mmm条边,qqq次询问连接区间[L,R][L,R][L,R]中的边后的连通块个数.强制在线. n,m,q≤2×105n,m,q\leq 2\times10^5n,m,q≤2×105 ...

  4. bzoj3514(LCT+主席树)

    题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...

  5. 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树

    [BZOJ3514]Codechef MARCH14 GERALD07加强版 Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行 ...

  6. BZOJ 3514 Codechef MARCH14 GERALD07 加强版 LCT+主席树

    题意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 分析: 据说有dalao会离线做这题? 看到L和R就能想到主席树?dalao们太强了-- 如果我们给出n个点,m ...

  7. BZOJ3514:GERALD07加强版(LCT,主席树)

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...

  8. HDU - 3804 Query on a tree(主席树维护最大值+离散化)

    题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...

  9. CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度

    题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...

  10. Codeforces Round #742 (Div. 2) E. Non-Decreasing Dilemma (线段树维护区间连续问题)

    题意: 操作1:把x位置的数字修改成y. 操作2:查询[l,r]之间不下降序列的个数. 题解: 线段树维护区间和问题 (这是套路,想不到只能说做题少别打我) . 用五个变量进行维护. sum区间总个数 ...

最新文章

  1. 正则表达式中的*,+,?以及\w和\W的区别等常见问题的总结
  2. 川大计算机考研2020招生数,四川大学等大学,2020年研究生招生简章发布,这3个信息很重要!...
  3. javascript之闭包理解以及应用场景
  4. 利用filter替换字符串中的空格
  5. Codeforces Round #572 (Div. 2)B
  6. 掌握这个分析方法,数据分析就学会了一半
  7. 轧机用弹性阻尼体反力计算_「轴承知识」轧机轴承故障频繁怎么办?必要的检查维护不可少...
  8. resharper 7.x 注册码key
  9. NetDevOps常用数据库python实战-MongoDB
  10. 【LeetCode】【数组】题号:*283,移动零
  11. C++构造函数(复制构造函数)、析构函数
  12. 会计云课堂实名认证后怎么更改_会计云课堂网上听课步骤详解
  13. python数据插补_Python直线插补
  14. SCI论文下载之chrome插件
  15. 基于multisim的fm调制解调_基于SDR的FM调制与解调器的实现
  16. [管理]鼎捷软件售后服务体验
  17. 初学卡尔曼滤波与扩展卡尔曼滤波
  18. 数据库表历史数据备份(定时任务)
  19. linux如何卸载oracle数据库实例,linux下删除oracle数据库实例
  20. PAT练习集L1之四(10分题之不仔细看头铁wa题)

热门文章

  1. 10--Django-ORM操作-choices参数、多对多的三种创建方式
  2. vue项目中如何简单的读取声音文件
  3. 程序员PK律师——瑞幸咖啡战局
  4. ros学习笔记13——unknown package [sensor_msgs] on search path [{{‘ros_to_deepstream
  5. HTML常用meta小结
  6. MySQL 事务隔离级别
  7. 原装MTL安全栅MTL7742
  8. PCB生产中的化学量监测--第四章翻译4.2.1
  9. HyperX Alloy Mars2游戏机械键盘,深耕专业电竞机游戏械键盘
  10. 误入 GitHub 游戏区,结果意外地收获颇丰