传送门

比较简单的一道回滚莫队吧。

每次询问用bitset优化kosaraju统计答案。

就是有点难调。

然后向dzyo学长学习了回滚莫队的一种简洁的实现方式,就是直接建立一个sqrt(m)∗sqrt(m)sqrt(m)*sqrt(m)sqrt(m)∗sqrt(m)的动态数组按块存储询问。

这样好写得多。

还有就是学习了korasaju用bitset优化的写法。

代码:

#include<bits/stdc++.h>
#define N 155
#define M 300005
#define sig 575
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
bitset<N>vis,e[N],g[N],tmp1[N],tmp2[N];
int n,m,q,U[M],V[M],bg[M],ed[M],tot=0,out[N],cnt,ans[M];
struct Query{int l,r,id;};
inline bool operator<(Query a,Query b){return a.r<b.r;}
vector<Query>qr[1005][1005];
inline void add(int u,int v){e[u].set(v),g[v].set(u);}
inline void dfs1(int p){
	bitset<N>tmp;
	vis[p]=1;
	while((tmp=e[p]^(e[p]&vis)),tmp.any()){
		int v=tmp._Find_first();
		dfs1(v);
	}
	out[++cnt]=p;
}
inline int dfs2(int p){
	bitset<N>tmp;
	vis[p]=1;
	int ret=1;
	while((tmp=g[p]^(g[p]&vis)),tmp.any()){
		int v=tmp._Find_first();
		ret+=dfs2(v);
	}
	return ret;
}
inline int kosaraju(){
	vis.reset(),cnt=0;
	for(int i=1;i<=n;++i)if(!vis[i])dfs1(i);
	vis.reset();
	int ret=0;
	for(int i=n;i;--i){
		if(!vis[out[i]]){
			int tmp=dfs2(out[i]);
			ret+=tmp*(tmp-1)/2;
		}
	}
	return ret;
}
inline void solve(int l,int r,int id){
	for(int i=l;i<=r;++i)add(U[i],V[i]);
	ans[id]=kosaraju();
	for(int i=1;i<=n;++i)e[i].reset(),g[i].reset();
}
int main(){
//	freopen("friend.in","r",stdin);
//	freopen("my.out","w",stdout);
	n=read(),m=read(),q=read();
	for(int i=1;i<=m;++i)U[i]=read(),V[i]=read();
	for(int l=1,r;l<=m;l=r+1)r=min(l+sig-1,m),bg[++tot]=l,ed[tot]=r;
	for(int i=1;i<=q;++i){
		int l=read(),r=read();
		if(r-l+1<=2*sig)solve(l,r,i);
		else qr[(l-1)/sig+2][r/sig].push_back((Query){l,r,i});
	}
	for(int i=1;i<=tot;++i)for(int j=1;j<=tot;++j)sort(qr[i][j].begin(),qr[i][j].end());
	for(int i=1;i<=tot;++i){
		int r=ed[i-1];
		for(int j=i;j<=tot;++j){
			while(r<ed[j])++r,add(U[r],V[r]);
			for(int k=0;k<qr[i][j].size();++k){
				Query pos=qr[i][j][k];
				while(r<pos.r)++r,add(U[r],V[r]);
				for(int l=1;l<=n;++l)tmp1[l]=e[l],tmp2[l]=g[l];
				for(int l=bg[i]-1;l>=pos.l;--l)add(U[l],V[l]);
				ans[pos.id]=kosaraju();
				for(int l=1;l<=n;++l)e[l]=tmp1[l],g[l]=tmp2[l];
			}
		}
		for(int j=1;j<=n;++j)e[j].reset(),g[j].reset();
	}
	for(int i=1;i<=q;++i)printf("%d\n",ans[i]);
	return 0;
}

2018.09.26 bzoj5218: [Lydsy2017省队十连测]友好城市(回滚莫队)的更多相关文章

  1. bzoj 5218: [Lydsy2017省队十连测]友好城市

    题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...

  2. loj#6517. 「雅礼集训 2018 Day11」字符串(回滚莫队)

    传送门 模拟赛的时候纯暴力竟然骗了\(70\)分-- 首先对于一堆\(g\)怎么计算概率应该很好想,用总的区间数减去不合法的区间数就行了,简而言之对\(g\)排个序,每一段长为\(d\)的连续序列的区 ...

  3. LOJ.6504.[雅礼集训2018 Day5]Convex(回滚莫队)

    LOJ 莫队.发现只需要维护前驱后继就可以了. 但是加入一个点需要找到它当前的前驱后继,很麻烦还带个\(\log\). 但是如果只有删除某个点,只需要更新一下它的前驱后继即可. 用回滚莫队就好惹. 撤 ...

  4. 2018.08.14 bzoj4241: 历史研究(回滚莫队)

    传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...

  5. LOJ#6504. 「雅礼集训 2018 Day5」Convex(回滚莫队)

    题面 传送门 题解 因为并不强制在线,我们可以考虑莫队 然而莫队的时候有个问题,删除很简单,除去它和前驱后继的贡献即可.但是插入的话却要找到前驱后继再插入,非常麻烦 那么我们把它变成只删除的回滚莫队就 ...

  6. BZOJ4241历史研究题解--回滚莫队

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4241 分析 这题就是求区间权值乘以权值出现次数的最大值,一看莫队法块可搞,但仔细想想,莫 ...

  7. BZOJ.4241.历史研究(回滚莫队 分块)

    题目链接 \(Description\) 长度为n的数列,m次询问,每次询问一段区间最大的 \(A_i*tm_i\) (重要度*出现次数) \(Solution\) 好像可以用莫队做,但是取max的操 ...

  8. BZOJ4241:历史研究(回滚莫队)

    Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...

  9. bzoj4241: 历史研究(回滚莫队)

    传送门 这是一个叫做回滚莫队的神奇玩意儿 是询问,而且不强制在线,就决定是你了莫队 如果是每次插入一个数是不是很简单? 然而悲剧的是我们莫队的时候不仅要插入数字还要删除数字 那么把它变成只插入不就行了 ...

随机推荐

  1. 5.mybatis实战教程(mybatis in action)之五:与spring3集成(附源码)

    转自:https://blog.csdn.net/nnn9223643/article/details/41962097 在 这一系列文章中,前面讲到纯粹用mybatis 连接数据库, 然后 进行增删 ...

  2. Gradle 语法

    参考文章: Gradle学习系列之二——创建Task的多种方法(http://www.cnblogs.com/CloudTeng/p/3417970.html) Gradle基本知识点与常用配置(ht ...

  3. 10 python 封装----@property的用法

    1.基本概念 在python中用双下划线开头的方式将属性隐藏起来(设置成私有的) #其实这仅仅这是一种变形操作 #类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式: class A ...

  4. 从底层谈WebGIS 原理设计与实现(二):探究本质,WebGIS前端地图显示之地图比例尺换算原理

    从底层谈WebGIS 原理设计与实现(二):探究本质,WebGIS前端地图显示之地图比例尺换算原理 作者:naaoveGI…    文章来源:http://www.cnblogs.com/naaove ...

  5. Redis用在哪里

    1. 高并发缓存/共享session:     UserInfo getUserInfo (long id) {}     取:     userRedisKey = "user:info: ...

  6. Haskell语言学习笔记(21)Array

    Ix 数组下标类型 Prelude> :m +Data.Array Prelude Data.Array> data Colour = Red | Orange | Yellow | Gr ...

  7. Dotfuscator Professional Edition获取代码发布和混淆代码

    1 Dotfuscator Professional Edition 4.9 破解版 下载地址:http://www.pc0359.cn/downinfo/39815.html 备份地址:C:\D\9 ...

  8. luoguP1090 合并果子 (贪心+优先队列)

    题目链接:https://www.luogu.org/problemnew/show/P1090 思路: 典型的贪心题,显然每次选择两个最小的堆合并最后耗费的体力最少,但每次合并之后都需要寻找最小的两 ...

  9. New Game! (最短路+建图)

    New Game! https://www.nowcoder.com/acm/contest/201/L 题目描述 Eagle Jump公司正在开发一款新的游戏.Hifumi Takimoto作为其中 ...

  10. js字符串解析成数字

    parseInt() 先把参数转换成字符串:左边有连续的数字则返回数值,若没有则返回NaN. console.log('parseInt(null)',parseInt(null)); // NaN ...