[清华集训2015 Day1]玛里苟斯-[线性基]
生活随笔
收集整理的這篇文章主要介紹了
[清华集训2015 Day1]玛里苟斯-[线性基]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Solution
?
考慮k=1的情況。假設所有數中,第i位為1的數的個數為x,則最后所有的子集異或結果中,第i位為1的個數為$(C_{k}^{1}+C_{k}^{3}+...)$*2原本的數中第i位為0的數的個數。同理,所有子集異或結果中第i位為0的個數為$(C_{k}^{0}+C_{k}^{2}+...)$*2原本的數中第i位為0的數的個數。
由于二項式定理,可得前后兩個式子大小相等。即對于每一位i,如果該位有某個(些)數為1,ans+=10i-1/2。
k=2同理。
對于k>2,我們發現假如某個數能夠由其他若干個數異或而得,那么把這個數刪掉對答案沒有影響。可以用線性基。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int N=1e5+10; typedef unsigned long long ull; int n,k,R;ull a[N]; ull b[30];int cnt; ull _ans,_res; void dfs(int x,ull c) {if (x==cnt+1){ull num=0,yu=1;for (int i=1;i<=k;i++){num*=c;yu*=c;num+=yu>>cnt;yu&=R;}_res+=yu;_ans+=num+(_res>>cnt);_res&=R;return;}dfs(x+1,c);dfs(x+1,c^b[x]); } int main() {scanf("%d%d",&n,&k);for (int i=1;i<=n;i++) scanf("%llu",&a[i]);if (k==1){ull t=0;for (int i=1;i<=n;i++) t|=a[i];printf("%llu%s",t>>1,t&1?".5":0);return 0;}if (k==2){ull t=0,ans=0;for (int i=1;i<=n;i++) t|=a[i];for (int i=0;i<32;i++) for (int j=i;j<32;j++)if (t>>i&&t>>j) ans+=1ull<<(i+j);printf("%llu%s",ans>>1,ans&1?".5":0);return 0; }ull t[30];memset(t,0,sizeof(t));for (int i=1;i<=n;i++)for (int j=21;j>=0;j--){if (a[i]&(1<<j)) if (!t[j]) {t[j]=a[i];break;} a[i]^=t[j]; }for (int i=0;i<=21;i++) if (t[i]) b[++cnt]=t[i];R=(1<<cnt)-1;dfs(1,0);if (_res) printf("%llu.5",_ans);else printf("%llu",_ans); }?
轉載于:https://www.cnblogs.com/coco-night/p/9748177.html
總結
以上是生活随笔為你收集整理的[清华集训2015 Day1]玛里苟斯-[线性基]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wps一直显示正在备份怎么办_wps怎么
- 下一篇: 散文说python半篇——景观三元论与盖