2018.09.26 bzoj5218: [Lydsy2017省队十连测]友好城市(回滚莫队)
传送门
比较简单的一道回滚莫队吧。
每次询问用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省队十连测]友好城市(回滚莫队)的更多相关文章
- bzoj 5218: [Lydsy2017省队十连测]友好城市
题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...
- loj#6517. 「雅礼集训 2018 Day11」字符串(回滚莫队)
传送门 模拟赛的时候纯暴力竟然骗了\(70\)分-- 首先对于一堆\(g\)怎么计算概率应该很好想,用总的区间数减去不合法的区间数就行了,简而言之对\(g\)排个序,每一段长为\(d\)的连续序列的区 ...
- LOJ.6504.[雅礼集训2018 Day5]Convex(回滚莫队)
LOJ 莫队.发现只需要维护前驱后继就可以了. 但是加入一个点需要找到它当前的前驱后继,很麻烦还带个\(\log\). 但是如果只有删除某个点,只需要更新一下它的前驱后继即可. 用回滚莫队就好惹. 撤 ...
- 2018.08.14 bzoj4241: 历史研究(回滚莫队)
传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...
- LOJ#6504. 「雅礼集训 2018 Day5」Convex(回滚莫队)
题面 传送门 题解 因为并不强制在线,我们可以考虑莫队 然而莫队的时候有个问题,删除很简单,除去它和前驱后继的贡献即可.但是插入的话却要找到前驱后继再插入,非常麻烦 那么我们把它变成只删除的回滚莫队就 ...
- BZOJ4241历史研究题解--回滚莫队
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4241 分析 这题就是求区间权值乘以权值出现次数的最大值,一看莫队法块可搞,但仔细想想,莫 ...
- BZOJ.4241.历史研究(回滚莫队 分块)
题目链接 \(Description\) 长度为n的数列,m次询问,每次询问一段区间最大的 \(A_i*tm_i\) (重要度*出现次数) \(Solution\) 好像可以用莫队做,但是取max的操 ...
- BZOJ4241:历史研究(回滚莫队)
Description IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. ...
- bzoj4241: 历史研究(回滚莫队)
传送门 这是一个叫做回滚莫队的神奇玩意儿 是询问,而且不强制在线,就决定是你了莫队 如果是每次插入一个数是不是很简单? 然而悲剧的是我们莫队的时候不仅要插入数字还要删除数字 那么把它变成只插入不就行了 ...
随机推荐
- HTML5 Canvas ( 绘制一轮弯月, 星空中的弯月 )
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- leetcode217
public class Solution { public bool ContainsDuplicate(int[] nums) { var list = nums.Distinct(); if ( ...
- 万字总结:学习MySQL优化原理,这一篇就够了!
前言 说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的 ...
- 怎样在Windows本地搭建redis服务器
1.下载最新redis https://github.com/MicrosoftArchive/redis/releases 2.解压如果是mis 版本直接下一步下一步即可 3.接下来我们 ...
- 机器学习入门-DBSCAN聚类算法
DBSCAN 聚类算法又称为密度聚类,是一种不断发张下线而不断扩张的算法,主要的参数是半径r和k值 DBSCAN的几个概念: 核心对象:某个点的密度达到算法设定的阈值则其为核心点,核心点的意思就是一个 ...
- javaEncode
1.MD5加密 md5多用于用户密码加密或者签名使用,因md5不可逆,可用于身份验证. MessageDigest md5=MessageDigest.getInstance("MD5&qu ...
- 基于OpenGL编写一个简易的2D渲染框架-12 重构渲染器-BlockAllocator
BlockAllocator 的内存管理情况可以用下图表示 整体思路是,先分配一大块内存 Chunk,然后将 Chunk 分割成小块 Block.由于 Block 是链表的一个结点,所以可以通过链表的 ...
- Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数
Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数~~~ 呵呵... 看着有点晕.. 再解释一下就是 在Unity中 使用 C# 调用 C++ 写的 DLL, 但是在 ...
- Delphi编程实现是否开启“平滑屏幕字体边缘“
在Windows高级设置中的视觉效果中可以设置是否开启“平滑屏幕字休边缘”,可以通过编程的方式来实现: if SystemParametersInfo(SPI_SETFONTSMOOTHING, 1, ...
- break、continue、pass介绍
break.continue.pass介绍 break:跳出当前循环 continue:跳出本次循环,进行下一次循环 pass:什么也不做,占位.