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

  • 相关阅读:
    LeetCode 275. H-Index II
    LeetCode 274. H-Index
    LeetCode Gray Code
    LeetCode 260. Single Number III
    LeetCode Word Pattern
    LeetCode Nim Game
    LeetCode 128. Longest Consecutive Sequence
    LeetCode 208. Implement Trie (Prefix Tree)
    LeetCode 130. Surrounded Regions
    LeetCode 200. Number of Islands
  • 原文地址:https://www.cnblogs.com/petjelinux/p/13605400.html
Copyright © 2011-2022 走看看