sosdp 二進位制子集的貢獻

2022-07-23 17:18:24 字數 2925 閱讀 4222

可以o(n*2^n)算出n位每個mask值所包含子集的二進位製碼下標的貢獻

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

1 #include2

//#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 }

view code

**是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 #include2

//#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 }

view code

二進位制子集生成

之前看 演算法競賽入門經典 這本書,看到了子集生成部分,以為自己沒有看二進位制法。誰知整理部落格的時候發現很早之前就學習過了,然而我描述的不完整,看了半天沒看懂什麼意思,果然欠下的都是要還的。用二進位制表示子集,其中從右往左第i位 從0開始編號 表示元素i是否在集合中。在集合表示法中,1 i 表示第...

二進位制列舉子集

利用二進位制的 開關 特性列舉 詳細為 如果給定集合a大小為n,則想象a 的每乙個元素相應乙個開關位 0或1 0表示不出現,1表示出現。當每乙個元素的開關位的值確定時,就得到乙個子集。因此共同擁有2 n 1種情況 全0為空集,這裡不考慮 我們利用區間 1,2 n 1 該區間上的每乙個整數相應乙個子集...

二進位制 二進位制起源

現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...