【hdu6072】Logical Chain

Kosaraju算法,然後bitset優化

主要是學習一下自寫bitset的姿勢

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define dow(i,l,r) for(int i=r;i>=l;i--)
#define rep0(i,r) for(int i=0;i<r;i++)
#define repedge(i,x) for(int i=cur[x];i>=0;i=e[i].next)
#define maxn 550
#define maxm 100100
#define LL long long
using namespace std;

int tot,p[maxn],n,m,kk;
char s[maxn];

struct Bitset{
    unsigned int v[8];
    void reset()  //clear
    {
        memset(v,0,sizeof(v));
    }
    void set(int x) //set v[x]=1
    {
        v[x>>5]|=1u<<(x&31);
    }
    void flip(int x) // rev
    {
        v[x>>5]^=1u<<(x&31);
    }
    bool ask(int x)  // is == 1?
    {
        return v[x>>5]>>(x&31)&1;
    }
}vis,g[maxn],rg[maxn];
//vis[] =1 not vis,=0 vis
//g[i][j] =1 exist i->j,=0 not exist
//rg[i][j] =1 exist j->i,=0 not exist;

void add(int j,int k)
{
    g[j].flip(k);
    rg[k].flip(j);
}

int nlz(unsigned int x)
{
   int n;
   n = 1;
   if ((x >> 16) == 0) {n = n +16; x = x <<16;}
   if ((x >> 24) == 0) {n = n + 8; x = x << 8;}
   if ((x >> 28) == 0) {n = n + 4; x = x << 4;}
   if ((x >> 30) == 0) {n = n + 2; x = x << 2;}
   n = n - (x >> 31);
   return 31-n;
}

void dfs0(int x)
{
    vis.flip(x);
    rep0(i,8) {
        unsigned int now=vis.v[i]&g[x].v[i];
        while (now) {
            dfs0(i<<5|nlz(now));
            now=vis.v[i]&g[x].v[i];
        }
    }
    p[++tot]=x;
}

void dfs1(int x)
{
    vis.flip(x);
    ++tot;
    rep0(i,8) {
        unsigned int now=vis.v[i]&rg[x].v[i];
        while (now) {
            dfs1(i<<5|nlz(now));
            now=vis.v[i]&rg[x].v[i];
        }
    }
}

int calc()
{
    vis.reset();
    rep0(i,n) vis.set(i);
    tot=0;
    rep0(i,n)
        if (vis.ask(i)) dfs0(i);
    rep0(i,n) vis.set(i);
    int ans=0;
    dow(i,1,n)
        if (vis.ask(p[i])) {
            tot=0;
            dfs1(p[i]);
            ans+=tot*(tot-1)/2;
        }
    return ans;
}

int main()
{
    int tt;
    scanf("%d",&tt);
    while (tt--) {
        scanf("%d %d",&n,&m);
        rep0(i,n) {
            g[i].reset();
            rg[i].reset();
        }
        rep0(i,n) {
            scanf("%s",s);
            rep0(j,n)
                if (s[j]==‘1‘) add(i,j);
        }
        while (m--) {
            scanf("%d",&kk);
            while (kk--) {
                int j,k;
                scanf("%d %d",&j,&k);
                add(j-1,k-1);
            }
            printf("%d\n",calc());
        }
    }
    return 0;
}

另外是一個總結

Bitset
头文件:#include<bitset>
bitset<32> bits;
b.any() b中是否存在置为1的二进制位?
b.none() b中不存在置为1的二进制位吗?
b.count() b中置为1的二进制位的个数
b.size() b中二进制位数的个数
b[pos] 访问b中在pos处二进制位
b.test(pos) b中在pos处的二进制位置为1么?
b.set() 把b中所有二进制位都置为1
b.set(pos) 把b中在pos处的二进制位置为1
b.reset( ) 把b中所有二进制位都置为0
b.reset( pos ) 把b中在pos处的二进制位置置为0
b.flip( ) 把b中所有二进制位逐位取反
b.flip( pos ) 把b中在pos处的二进制位取反
b.to_ulong( ) 把b中同样的二进制位返回一个unsigned

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的奇偶性

时间: 2024-11-07 15:17:56

【hdu6072】Logical Chain的相关文章

【转】cache buffer chain 第一篇

文章转自:http://www.jydba.net/cache-buffer-chain/ buffer cache的管理有两个重要的数据结构: hash bucket和cache buffer chain 1. hash bucket和cache buffer chain 可以想象,如果所有的buffer cache中的所有buffer都通过同一个结构来进行管理,当需要确定某个 block在buffer中是否存在时,将需要遍历整个结构,性能会相当低下. 为了提高效率,oracle引入了buck

【struts2】名为chain的ResultType

1)基本使用 名称为"chain"的ResultType,在struts-default.xml里的配置如下: <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> chain是一种特殊的视图结果,用来将Action执行完之后链接到另一个Action中继续执行,新的Action使用上一个Action的上下文(ActionContext

【转】Cache Buffer Chain 第二篇

文章转自:http://m.bianceng.cn/database/Oracle/201407/42884.htm 测试环境:版本11gR2 SQL> select * from v$version where rownum=1; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Releas

【HDU3487】【splay分裂合并】Play with Chain

Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n.At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n.He will perform two types of operations:CUT a b c

【转】Life of a triangle - NVIDIA&#39;s logical pipeline

From:https://developer.nvidia.com/content/life-triangle-nvidias-logical-pipeline Since the release of the ground breaking Fermi architecture almost 5 years have gone by, it might be time to refresh the principle graphics architecture beneath it. Ferm

【POJ 2248】 Addition Chain

[题目链接] http://poj.org/problem?id=2248 [算法] 搜索剪枝 剪枝1 : 优化搜索顺序,从大到小枚举 剪枝2 : Ai + Aj可能相等,只需搜一次即可 剪枝3 : 通过观察发现 : m <= 10,可以用迭代加深搜索 [代码] #include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale&

【struts2】预定义拦截器

1)预定义拦截器 Struts2有默认的拦截器配置,也就是说,虽然我们没有主动去配置任何关于拦截器的东西,但是Struts2会使用默认引用的拦截器.由于Struts2的默认拦截器声明和引用都在这个Struts-default.xml里面,因此我们需要到这个文件的struts-default包里去看一下.定义如下: 1 <interceptors> 2 <interceptor name="alias" class="com.opensymphony.xwor

【转】《windows核心编程》读书笔记

这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入,但应该是合理的.开头几章由于我追求简洁,往往是很多单独的字句,后面的内容更为连贯. 海量细节. 第1章    错误处理 1.         GetLastError返回的是最后的错误码,即更早的错误码可能被覆盖. 2.         GetLastError可能用于描述成功的原因(CreatEvent)

【DATAGUARD】物理dg配置客户端无缝切换--Fast-Start Failover的配置

[DATAGUARD]物理dg配置客户端无缝切换--Fast-Start Failover的配置 一.2.2  实验环境介绍 项目 主库 dg库 db 类型 单实例 单实例 db version 11.2.0.3 11.2.0.3 db 存储 FS type FS type ORACLE_SID oradg11g oradgphy db_name oradg11g oradg11g 主机IP地址: 192.168.59.130 192.168.59.130 OS版本及kernel版本 RHEL6