HDU 6072 Logical Chain(Kosaraju+bitset)
http://acm.hdu.edu.cn/showproblem.php?pid=6072
题意:
给你$n*n$的矩阵,每次修改k条边,让你计算其中能相互到达的点对有多少。
思路:
其实就是求强连通分量,如果一个强连通分量里有n个点,那么这里面的点对就有$n*(n-1)/2$。用Kosaraju计算即可,但是这样是会超时的,还需要用bitset来优化。
__builtin_函数中处理二进制位的函数:
int __builtin_ffs (unsigned x) 返回x中最后一个1是从右往左第几位
int __builtin_popcount (unsigned x) 返回x中1的个数
int __builtin_ctz (unsigned x) 返回x末尾0的个数(x等于0时未定义)
int __builtin_clz (unsigned x) 返回x中前导0的个数(x等于0时未定义)
int __builtin_parity (unsigned x) 返回x中1的奇偶性
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m;
int num;
char s[maxn]; struct Bitset//用unsigned数组实现bitset,为了使用__builtin_ctz()
{
unsigned v[];//8个unsigned表示8*32=256位 void reset()//清零
{
for(int i=;i<;++i) v[i]=;
}
void set(int x)//把某一位设为1
{
v[x>>]|=1u<<(x&);
}
void flip(int x)//翻转某一位
{
v[x>>]^=1u<<(x&);
}
bool test(int x)//返回某一位是否为1
{
return v[x>>]>>(x&)&;
}
}vis, G[maxn], rG[maxn]; vector<int> S; void dfs1(int u)
{
vis.flip(u);
for(int i=;i<;i++)
{
while(true)
{
unsigned tmp=vis.v[i]&G[u].v[i]; //tmp就计算出了可以访问的点
if(!tmp) break;
dfs1(i<<|__builtin_ctz(tmp)); //计算出tmp末尾有多少0,有多少0就代表了它是第几位,这儿的话一个点一个点的来
}
}
S.push_back(u);
} void dfs2(int u)
{
vis.flip(u);
++num;
for(int i=;i<;i++)
{
while(true)
{
unsigned tmp=vis.v[i]&rG[u].v[i];
if(!tmp) break;
dfs2(i<<|__builtin_ctz(tmp));
}
}
} void Kosaraju()
{
S.clear();
int ans=;
for(int i=;i<n;i++) vis.set(i);
for(int i=;i<n;i++) if(vis.test(i)) dfs1(i);
for(int i=;i<n;i++) vis.set(i);
for(int i=n-;i>=;i--)
{
if(vis.test(S[i]))
{
num=;
dfs2(S[i]);
ans+=num*(num-)/;
}
}
printf("%d\n",ans);
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) G[i].reset(),rG[i].reset();
for(int i=;i<n;i++)
{
scanf("%s",s);
for(int j=;j<n;j++) if(s[j]=='')
{
G[i].flip(j);
rG[j].flip(i);
}
}
while(m--)
{
int t; scanf("%d",&t);
while(t--)
{
int u,v;
scanf("%d%d",&u,&v);
G[u-].flip(v-);
rG[v-].flip(u-);
}
Kosaraju();
}
}
return ;
}
HDU 6072 Logical Chain(Kosaraju+bitset)的更多相关文章
- HDU 3980 Paint Chain (sg函数)
Paint Chain Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU - 3980 Paint Chain(SG函数)
https://vjudge.net/problem/HDU-3980 题意 一串长度为n的柱子,每个人只能给连续的珠子涂色,涂过的不能再涂,不能涂的人就输了,问最后谁获胜. 分析 第一个人先涂m个, ...
- HDU 5860 Death Sequence(死亡序列)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- HDU 5877 Weak Pair(弱点对)
HDU 5877 Weak Pair(弱点对) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Jav ...
- HDU 5813 Elegant Construction(优雅建造)
HDU 5813 Elegant Construction(优雅建造) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65 ...
- HDU 5818 Joint Stacks(联合栈)
HDU 5818 Joint Stacks(联合栈) Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- HDU 2222 Keywords Search(查询关键字)
HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...
- HDU 3549 Flow Problem(最大流)
HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
- HDU 4548 美素数(打表)
HDU 4548 美素数(打表)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88159#problem/H 题目 ...
随机推荐
- SeaJS 与 RequireJS 的差异对比
这篇文章主要介绍了SeaJS 与 RequireJS 的差异对比,本文主要对CMD规范和AMD规范的弊端做了对比,并做出了一个总结,需要的朋友可以参考下 “历史不是过去,历史正在上演.随着 W3C 等 ...
- 深入理解Fabric环境搭建的详细过程(转)
前面的准备工作我就不用多说了,也就是各种软件和开发环境的安装,安装好以后,我们git clone下来最新的代码,并切换到v1.0.0,并且下载好我们需要使用的docker镜像,也就是到步骤6,接下来我 ...
- test examples/test scripts
//https://www.getpostman.com/docs/v6/postman/scripts/test_examples //Setting an environment variable ...
- VMware Coding Challenge: Removing Duplicates Entries
static LinkedListNode removeDuplicates(LinkedListNode list) { LinkedListNode cur = list; HashSet< ...
- JQuery中如何使用事件来出发Ajax
$(document).ready(function(){ $("input[name='customer_name']").keydown(func ...
- mysql性能优化2
sql语句优化 性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的 ...
- pandas练习(一)------ 了解数据
探索Chipotle快餐数据 (相关数据见github) 步骤1 导入pandas库 import pandas as pd 步骤2 导入数据集 path1 = "./data/chipot ...
- linux常用命令:ping 命令
Linux系统的ping 命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地 址192.168.1.1试试 ...
- 用Python实现随机森林算法,深度学习
用Python实现随机森林算法,深度学习 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱.bagging(bootstrap aggregating 的缩 ...
- c++获取时间戳
vc获取时间戳的代码如下: SYSTEMTIME st; }; GetLocalTime(&st); // vc专用 _snprintf_s(ts, sizeof(ts), "%4d ...