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)的更多相关文章

  1. HDU 3980 Paint Chain (sg函数)

    Paint Chain Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDU - 3980 Paint Chain(SG函数)

    https://vjudge.net/problem/HDU-3980 题意 一串长度为n的柱子,每个人只能给连续的珠子涂色,涂过的不能再涂,不能涂的人就输了,问最后谁获胜. 分析 第一个人先涂m个, ...

  3. HDU 5860 Death Sequence(死亡序列)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  4. HDU 5877 Weak Pair(弱点对)

    HDU 5877 Weak Pair(弱点对) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Jav ...

  5. HDU 5813 Elegant Construction(优雅建造)

    HDU 5813 Elegant Construction(优雅建造) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65 ...

  6. HDU 5818 Joint Stacks(联合栈)

    HDU 5818 Joint Stacks(联合栈) Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  7. HDU 2222 Keywords Search(查询关键字)

    HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...

  8. HDU 3549 Flow Problem(最大流)

    HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...

  9. HDU 4548 美素数(打表)

    HDU  4548  美素数(打表)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88159#problem/H 题目 ...

随机推荐

  1. Sql Server 2016 Always On集群搭建

    第一步,配置好windows环境 第二步 (配置内容较多--需单写) 需要做windows集群 安装WSFC集群组件 直接在Windows服务器管理工具中,增加功能模块,集群故障转移模块 并增加节点 ...

  2. HTML方法

    HTTP 方法:GET 对比 POST 两种最常用的 HTTP 方法是:GET 和 POST. 什么是 HTTP ? 超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信. HTTP 的 ...

  3. 顺序结构,判断结构 if,switch

    1:顺序结构:从上往下执行程序代码,为顺序结构 ---------------------------------------------------------------------- 2:判断结 ...

  4. Python线程,进程,携程,I/O同步,异步

    只有本人能看懂的-Python线程,进程,携程,I/O同步,异步 举个栗子: 我想get三个url,先用普通的for循环 import requests from multiprocessing im ...

  5. dialog提交表单

    <div id="dialog" title="添加客户"> <!--表单提交--> <form id="dialogF ...

  6. 好消息啊,有些c似乎不用加厂商前缀了

    今天写程序,一个不小心,没写厂商前缀,然而,,,,,,, 可以运行了(我居然不知道这个消息!!!!) 赶紧写几个字纪念一下. (把鼠标移动到红色的字上边~~~) don' you think that ...

  7. java的时间处理

    采用joda.time库 gradle,可以简化calendar的 compile "joda-time:joda-time:2.7" 例子:http://blog.csdn.ne ...

  8. Geometry

    uva1473 这题说的是 在空间中给了n个点 然后用体积最小的圆锥将这些点包含在内可以在表面上, 将这些点 映射到xoz平面上然后,然后枚举每个上凸包的边和每个点的极值进行判断求得最小的体积 我们会 ...

  9. Linux 使用系统ISO制作yum源

    关于linux安装问题,大多数情况下 系统开发完成之后,需要部署到生产机器上,客户提供的机器预装好了操作系统,但是都是内网环境 与外网都是物理隔绝的,那么 在搭建生产环境时需要安装相关软件时,如果自己 ...

  10. linux常用命令:find 命令参数详解

    find一些常用参数的一些常用实例和一些具体用法和注意事项. 1.使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用.  可以使用某种文件名模式来匹配 ...