zoukankan      html  css  js  c++  java
  • bitset在acm中的应用

    ps:最近碰到一些用bitset优化常数的题目,以前也有接触但是都没有记下来,所以来写一篇博文 记录以后碰到的类似的题目。


    应用一: 优化boolean multiplication

    在做dp的时候,有时候会需要将两个dp矩阵相乘,且矩阵的元素都是bool型。

    计算矩阵A*B=C     C[i,j]=1 当且仅当存在k,A[i,k]=1 && B[k][j]=1 。

    直接算需要O(n3)的时间。可以用bitset 优化常数。 做法如下:

     1 bitset<N> A[N],B[N],C[N];
     2 
     3 void Multi(bitset<N> A[],bitset<N> B[],bitset<N> C[])
     4 {
     5     for (int i=0;i<N;i++)
     6     {
     7         for (int j=0;j<N;j++)
     8         {
     9             if (A[i][j]) C[i]|=B[j];
    10         }
    11     }
    12 } 

    大致思想是:

    如果A[i][j]=1,  C[i][k] |= A[i][j] & B[j][k]    <->  C[i][k] |= B[j][k]     相当于把B的第j行拿去 和C的第i行做一次或操作。

    题目:

    http://codeforces.com/contest/781/problem/D

    该题的dp矩阵是boolean矩阵,转移的时候可以用bitset来优化boolean multiplication。

     1 #include <iostream>
     2 #include <string>
     3 #include <cstring>
     4 #include <map>
     5 #include <cmath>
     6 #include <set>
     7 #include <bitset>
     8 using namespace std;
     9 
    10 typedef long long ll;
    11 
    12 #define N 510
    13 
    14 bitset<N> dp[61][2][N];
    15 
    16 int main()
    17 {
    18     //freopen("in.in","r",stdin);
    19     //freopen("out.out","w",stdout);
    20     
    21     int n,m,x,y,z;
    22     scanf("%d%d",&n,&m);
    23     while (m--)
    24     {
    25         scanf("%d%d%d",&x,&y,&z);
    26         x--,y--,dp[0][z][x][y]=1;
    27     }
    28 
    29     for (int l=1;l<=60;l++)
    30     {
    31         for (int i=0;i<n;i++)
    32         {
    33             for (int j=0;j<n;j++)
    34             {
    35                 if (dp[l-1][0][i][j]) dp[l][0][i]|=dp[l-1][1][j];
    36                 if (dp[l-1][1][i][j]) dp[l][1][i]|=dp[l-1][0][j];
    37             }
    38         }
    39     }
    40     ll ans=0; set<int> S; S.insert(0);
    41     for (int l=60,w=0;l>=0 && ans<=1e18;l--)
    42     {
    43         set<int> SS;
    44         for (set<int>::iterator iter=S.begin();iter!=S.end();iter++)
    45         {
    46             int x=*iter; 
    47             for (int j=0;j<n;j++)  if (dp[l][w][x][j]) SS.insert(j);
    48         }
    49         if (!SS.empty()) ans+=1ll<<l,S=SS,w^=1;
    50     }
    51     if (ans>1e18) ans=-1;
    52     printf("%I64d
    ",ans);
    53     return 0;
    54 }
    View Code

    待补充...

  • 相关阅读:
    查询datatime类型
    ms的题目,无聊不妨看看
    读取客户端收藏夹资料的问题
    delphi中的DBGrid无法刷新数据
    jsp与javascript
    .net2.0 web site中的cs文件怎么编译为dll
    由传奇木马引起的遐想
    com组件的调用
    Crystal Report的奇怪问题
    算法导论15章LCS实现(c++)
  • 原文地址:https://www.cnblogs.com/vb4896/p/6524682.html
Copyright © 2011-2022 走看看