可以o(n*2^n)算出n位每個mask值所包含子集的二進位製碼下標的貢獻
比如f[5]=a[0]+a[1]+a[4]+a[5]這種的,101包含了000,001,100,101
1 #include2view code//#pragma comment(linker, "/stack:1024000000,1024000000")
3 #include4 #include5 #include6 #include
7 #include8 #include9 #include10 #include
11 #include12 #include13 #include14 #include15 #include16
17using
namespace std; //
1819
#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))
25ll qp(ll a,ll b,ll mod)return
t;27}28
struct dot;
29 inline void read(int &x)
30void ex()
31const
int dx[8]=;
32const
int dy[8]=;
33const
int inf=0x3f3f3f3f
; 34
const ll linf=0x3f3f3f3f3f3f3f3fll;
35const ll mod=1e18+7;36
const
double eps=1e-6;37
const
double pi=acos(-1.0
);38
39const
int maxn=1e6+33;40
41int
n;42
inta[maxn],f[maxn];
4344
intmain()
49for(int i=0;i
52for(int i=0;i)57}
58 }
**是cf上的一篇部落格
核心思想就是從低位列舉到高位,
f[mask][i]表示mask碼低i位子集的貢獻
如果mask的第i位是1,那麼f[mask][i]=f[mask][i-1]+f[mask^(1如果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 #include2view code//#pragma comment(linker, "/stack:1024000000,1024000000")
3 #include4 #include5 #include6 #include
7 #include8 #include9 #include10 #include
11 #include12 #include13 #include14 #include15 #include16
17using
namespace std; //
1819
#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))
25ll qp(ll a,ll b,ll mod)return
t;27}28
struct dot;
29 inline void read(int &x)
30void ex()
31const
int dx[8]=;
32const
int dy[8]=;
33const
int inf=0x3f3f3f3f
; 34
const ll linf=0x3f3f3f3f3f3f3f3fll;
35const ll mod=1e18+7;36
const
double eps=1e-6;37
const
double pi=acos(-1.0
);38
39const
int maxn=1e6+3;40
41int n;int b[100011
];42
inta[maxn],f[maxn];
43int
t;44
intmain()
5354
for(int i=0;i)
57int lim=log2(maxn);
58for(int i=0;i)63}
64 ll ans=0;65
66for(int i=0;i)
69 printf("
%lld\n
",ans);70}
71 }
二進位制子集生成
之前看 演算法競賽入門經典 這本書,看到了子集生成部分,以為自己沒有看二進位制法。誰知整理部落格的時候發現很早之前就學習過了,然而我描述的不完整,看了半天沒看懂什麼意思,果然欠下的都是要還的。用二進位制表示子集,其中從右往左第i位 從0開始編號 表示元素i是否在集合中。在集合表示法中,1 i 表示第...
二進位制列舉子集
利用二進位制的 開關 特性列舉 詳細為 如果給定集合a大小為n,則想象a 的每乙個元素相應乙個開關位 0或1 0表示不出現,1表示出現。當每乙個元素的開關位的值確定時,就得到乙個子集。因此共同擁有2 n 1種情況 全0為空集,這裡不考慮 我們利用區間 1,2 n 1 該區間上的每乙個整數相應乙個子集...
二進位制 二進位制起源
現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...