zoukankan      html  css  js  c++  java
  • D. The Wu 解析(思維、二進位運算)

    Codeforce 1017 D. The Wu 解析(思維、二進位運算)

    今天我們來看看CF1017D
    題目連結

    題目
    略,請直接看原題

    前言

    官方解答實在看不懂...之後還記得的話再補那個做法吧

    想法

    只要注意到(nle12)代表所有可能出現的數字(lesumlimits_{i=0}^{11}2^i=2^{12}-1=4096-1),那就會注意到這題的(m,qle5cdot10^5)是假的,因為總共也才(4096)種字串,哪來的(5cdot10^5)這麼多數字讓你問?
    所以這題只需要把所有的詢問字串都窮舉一遍,並且直接計算「當前詢問字串與(m)(multiset)裡的字串計算Wu值,每個值有多少個」儲存起來(只需要儲存Wu值(le100),因為(kle100)),那麼之後每次詢問只需要(O(100))就可以找到答案了(計算前綴和)。

    實作細節:首先把(multiset)裡的元素都看成數字;(cnt[i]=multiset)(i)的個數;((s,t))的Wu值只和(s,t)哪些(bit)相同有關,(wu[(s,t)兩個數字bit相同的位置標為1其他為0的數字]=Wu(s,t))
    而要計算(s,t)兩個數字bit相同的位置標為1其他為0的數字只需要:((swidehat{}(sim t))&((1<<n)-1)=(swidehat{}(sim t))&sim-(1<<n)),其中((1<<n)-1是用來只保留小於1<<n的bit),而((1<<n)-1=sim-(1<<n))是利用(-k=sim k+1)

    程式碼:

    const int _n=15;
    int t,n,m,q,w[_n],k,cnt[4096],ans[4096][110],wu[4096];
    char s[_n];
    main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
      cin>>n>>m>>q;rep(i,1,n+1)cin>>w[i];
      rep(i,0,1<<n)rep(j,0,n)wu[i]+=w[n-j]*((i&(1<<j))>0);
      rep(i,0,m){
        int num=0;cin>>(s+1);
        rep(j,0,n)num+=(s[n-j]-'0')*(1<<j);
        cnt[num]++;
      }rep(qu,0,1<<n)rep(ts,0,1<<n){
        ans[qu][wu[(qu^~ts)&~-(1<<n)]>100?101:wu[(qu^~ts)&~-(1<<n)]]+=cnt[ts];
      }while(q--){
        cin>>(s+1)>>k;
        t=0;rep(j,0,n)t+=(s[n-j]-'0')*(1<<j);
        int res=0;rep(i,0,k+1)res+=ans[t][i];
        cout<<res<<'
    ';
      }
      return 0;
    }
    

    標頭、模板請點Submission看
    Submission

  • 相关阅读:
    unistd.h文件
    error C3861: “getpid”: 找不到标识符
    #include <unistd.h> 的作用
    VS2013 配置pthread
    VS2008和VC6.0下使用pthread.h头文件
    文件下载之断点续传(客户端与服务端的实现)
    C++ 判断进程是否存在
    C/C++遍历进程和进程ID的小工具
    linux --> 文件系统十问
    网络通信 --> CRC校验
  • 原文地址:https://www.cnblogs.com/petjelinux/p/13605400.html
Copyright © 2011-2022 走看看