zoukankan      html  css  js  c++  java
  • 大杀器Bitset

    其实并不怎么会用,有一次有位学长提到了这个名字,就这么取题目了。

    1.BZOJ 3687 简单题

    求子集的算术和的异或和

    http://www.lydsy.com/JudgeOnline/problem.php?id=3687

    我们并不需要知道每个数(和)出现了多少次,只需知道它出现了奇数次还是偶数次,于是用一个二进制串表示。初始化dp[0]=1;

    加进一个数x,在原先集合的基础上,每个数+x出现的次数会++,就直接异或上集合左移x

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<bitset>
    using namespace std;
    const int maxn=2000000+299;
    bitset<maxn>b;
    int n,x,sum,ans;
    int main()
    {
       scanf("%d",&n);
       b[0]=1;
       while(n--){
           scanf("%d",&x);
           sum+=x;
           b^=(b<<x);
       }
       for(int i=1;i<=sum;i++)
        if(b[i])
          ans^=i;
       printf("%d
    ",ans);
       return 0;
    }
    BZOJ 3687 简单题

     

    2.BZOJ 4478 侦探jyy

    一开始我和SXY大佬都写了一种神奇地求出一个top即某两个点的上面的一个交点来判断是否一定发生的算法,虽然SXY的算法比我不知道高到哪里去了。骗了50分。然后轩神说,会有这种神奇的情况,没有交点,但是C发生了D一定发生

     

    于是正解是,对于每个发生的事件,向前跑一遍会导致它发生的集合,然后这些集合的交集即为答案。

    这个就可以用Bitset来搞。

    //Twenty
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<bitset>
    const int N=1000+29;
    const int M=100000+29;
    using namespace std;
    bitset<N>d[N],ans;
    int xx,x,y,cntz,cntf,n,m,D,firz[N],nxtz[M],toz[M],firf[N],nxtf[M],tof[M],vis[N];
    inline int read(){
        char ch=getchar(); int ret=0,f=1;
        while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';
        return ret*f;
    }
    void addz(int u,int v){
        nxtz[++cntz]=firz[u]; firz[u]=cntz; toz[cntz]=v;
    }
    void addf(int u,int v){
        nxtf[++cntf]=firf[u]; firf[u]=cntf; tof[cntf]=v;
    }
    void dfs1(int x){
        vis[x]=1; d[x][x]=1;
        for(int i=firz[x];i;i=nxtz[i]){
            if(!vis[toz[i]])
                dfs1(toz[i]);
            d[x]|=d[toz[i]];
        }
    }
    void dfs2(int x){
        vis[x]=1;  //d[x][x]=1;
        bitset<N>tmp;
        if(firf[x]){
            if(!vis[tof[firf[x]]]) dfs2(tof[firf[x]]);
            tmp=d[tof[firf[x]]];
        }
        else return;
        for(int i=nxtf[firf[x]];i;i=nxtf[i]){
            if(!vis[tof[i]]) dfs2(tof[i]);
            tmp&=d[tof[i]];
        }
        d[x]|=tmp;
    }
    int main()
    {
       freopen("a.in","r",stdin);
       freopen("a.out","w",stdout);
       n=read(); m=read(); D=read();
       for(int i=1;i<=m;i++){
           x=read(); y=read();
           x--; y--;
           addz(x,y);
           addf(y,x);
       }
       for(int i=0;i<n;i++)
        if(!vis[i]) dfs1(i);
       memset(vis,0,sizeof(vis));
       for(int i=1;i<=D;i++){
           scanf("%d",&xx); xx--;
           if(!vis[xx]) dfs2(xx);
           ans|=d[xx];
       }
       for(int i=0;i<n;i++){
           if(ans[i])
            printf("%d ",i+1);
       }
       return 0;
    }
    BZOJ 4478 侦探jyy

     

    有人提供了一种神奇的算法,枚举每个不是发生点的点,把它标记为未发生,然后再这个限制条件下跑一遍看是否所以发生点都可以发生,若不能则此点一定发生。时间复杂度好像没保证,不过这个随机数据过掉了。

  • 相关阅读:
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
    检测到有潜在危险的 Request.Form 值
    jQuery校验
    C#客户端的异步操作
    泛型(一)
    c#面试题汇总
    多线程(下)
    多线程(上)
    线程篇(二)
    线程篇(一)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/7474537.html
Copyright © 2011-2022 走看看