zoukankan      html  css  js  c++  java
  • sosdp 二进制子集的贡献

    可以O(n*2^n)算出n位每个mask值所包含子集的二进制码下标的贡献

    比如f[5]=a[0]+a[1]+a[4]+a[5]这种的,101包含了000,001,100,101

     1 #include<bits/stdc++.h>  
     2 //#pragma comment(linker, "/STACK:1024000000,1024000000")   
     3 #include<stdio.h>  
     4 #include<algorithm>  
     5 #include<queue>  
     6 #include<string.h>  
     7 #include<iostream>  
     8 #include<math.h>                    
     9 #include<stack>
    10 #include<set>  
    11 #include<map>  
    12 #include<vector>  
    13 #include<iomanip> 
    14 #include<bitset>
    15 #include<stdint.h>
    16 
    17 using namespace std;         //
    18 
    19 #define ll long long  
    20 #define ull unsigned long long
    21 #define pb push_back  
    22 #define FOR(a) for(int i=1;i<=a;i++) 
    23 #define sqr(a) (a)*(a)
    24 #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    25 ll qp(ll a,ll b,ll mod){
    26     ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    27 }
    28 struct DOT{int x;int y;};
    29 inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
    30 void ex(){puts("NO");exit(0);}
    31 const int dx[8]={0,0,-1,1,-1,1,-1,1};
    32 const int dy[8]={1,-1,0,0,-1,1,1,-1};
    33 const int inf=0x3f3f3f3f; 
    34 const ll Linf=0x3f3f3f3f3f3f3f3fLL;
    35 const ll Mod=1e18+7;
    36 const double eps=1e-6;
    37 const double pi=acos(-1.0);
    38 
    39 const int maxn=1e6+33;
    40 
    41 int n;
    42 int a[maxn],f[maxn];
    43 
    44 int main(){
    45     scanf("%d",&n);
    46     for(int i=0;i<(1<<n);i++){
    47         scanf("%d",&a[i]);
    48     }
    49     for(int i=0;i<(1<<n);i++){
    50         f[i]=a[i];
    51     }
    52     for(int i=0;i<n;i++){
    53         for(int msk=0;msk<(1<<n);msk++){
    54             if(msk & (1<<i))
    55                 f[msk]+=f[msk^(1<<i)];
    56         }
    57     }
    58 }
    View Code

    来源是cf上的一篇博客

    核心思想就是从低位枚举到高位,

    f[mask][i]表示mask码低i位子集的贡献

    如果mask的第i位是1,那么f[mask][i]=f[mask][i-1]+f[mask^(1<<i)][i-1],很巧妙地以第i位的01作为子集划分

    如果mask的第i位是0,那么f[mask][i]=f[mask][i-1]

    ------------------------------------------------------------------------------------------------------------------------

    例题SPECIAL PAIRS

    1e5的数列问有多少个pair满足a[i]&a[j]=0

    对于a[i],与他匹配的a[j]一定都贡献进a[i]的补集,那么答案就是sigma(f[补ai])

     1 #include<bits/stdc++.h>  
     2 //#pragma comment(linker, "/STACK:1024000000,1024000000")   
     3 #include<stdio.h>  
     4 #include<algorithm>  
     5 #include<queue>  
     6 #include<string.h>  
     7 #include<iostream>  
     8 #include<math.h>                    
     9 #include<stack>
    10 #include<set>  
    11 #include<map>  
    12 #include<vector>  
    13 #include<iomanip> 
    14 #include<bitset>
    15 #include<stdint.h>
    16 
    17 using namespace std;         //
    18 
    19 #define ll long long  
    20 #define ull unsigned long long
    21 #define pb push_back  
    22 #define FOR(a) for(int i=1;i<=a;i++) 
    23 #define sqr(a) (a)*(a)
    24 #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    25 ll qp(ll a,ll b,ll mod){
    26     ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    27 }
    28 struct DOT{int x;int y;};
    29 inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
    30 void ex(){puts("NO");exit(0);}
    31 const int dx[8]={0,0,-1,1,-1,1,-1,1};
    32 const int dy[8]={1,-1,0,0,-1,1,1,-1};
    33 const int inf=0x3f3f3f3f; 
    34 const ll Linf=0x3f3f3f3f3f3f3f3fLL;
    35 const ll Mod=1e18+7;
    36 const double eps=1e-6;
    37 const double pi=acos(-1.0);
    38 
    39 const int maxn=1e6+3;
    40 
    41 int n;int b[100011];
    42 int a[maxn],f[maxn];
    43 int T;
    44 int main(){
    45     read(T);
    46     while(T--){
    47         memset(a,0,sizeof a);
    48         read(n);
    49         for(int i=0;i<n;i++){
    50             read(b[i]);
    51             a[b[i]]++;
    52         }
    53 
    54         for(int i=0;i<maxn;i++){
    55             f[i]=a[i];
    56         }
    57         int lim=log2(maxn);
    58         for(int i=0;i<lim;i++){
    59             for(int msk=0;msk<maxn;msk++){
    60                 if(msk & (1<<i))
    61                     f[msk]+=f[msk^(1<<i)];
    62             }
    63         }
    64         ll ans=0;
    65 
    66         for(int i=0;i<n;i++){
    67             ans+=f[((1<<lim)-1) ^ b[i]];
    68         }
    69         printf("%lld
    ",ans);
    70     }
    71 }
    View Code
  • 相关阅读:
    Linux shell 学习总结
    linux shell 比较总结
    NSURL基本操作 HA
    Mac node.js install HA
    nodejs学习资料收集 HA
    xcode技巧 HA
    google web app/enxtions 学习资料收集 HA
    Failed to upload *.app on Device 可能的解决方法 HA
    iphone开发常见问题小集2 HA
    cocos2d收集 HA
  • 原文地址:https://www.cnblogs.com/Drenight/p/9117399.html
Copyright © 2011-2022 走看看