日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ARC106E-Medals【hall定理,高维前缀和】

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ARC106E-Medals【hall定理,高维前缀和】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://atcoder.jp/contests/arc106/tasks/arc106_e


題目大意

nnn個員工,第iii個在[1,Ai][1,A_i][1,Ai?]工作,[Ai+1,2×Ai][A_i+1,2\times A_{i}][Ai?+1,2×Ai?]休息,[2×Ai+1,3×Ai][2\times A_i+1,3\times A_i][2×Ai?+1,3×Ai?]工作…以此類推。

然后每天可以為一個在工作的人發一枚獎牌,至少多少天才能讓每個人都有kkk塊獎牌。

1≤n≤18,1≤k,Ai≤1051\leq n\leq 18,1\leq k,A_i\leq 10^51n18,1k,Ai?105


解題思路

首先答案上限顯然是2×n×1052\times n\times 10^52×n×105(就是每個人輪流發)

然后考慮一個暴力的做法。先二分,然后把每天看做一個右邊的點,每個員工看做kkk個左邊的點,然后一個員工干活的天就連邊,之后暴力跑網絡流。

這樣顯然會TTT但是這是一個正解的啟示。

首先我們先拓寬一下hallhallhall定理,原來是2×k2\times k2×k個點的二分圖匹配左邊任意kkk個點都和右邊至少kkk個點匹配是這張圖有完全匹配的充要條件,但是不難發現如果右邊多加了幾個點顯然還是滿足條件的。

所以上面那個可以理解為左邊任意kkk個點都和右邊至少有kkk條連邊,然后不難發現段其實只有2n2^n2n種不同的,所以我們直接二分一個答案然后設fsf_sfs?表示包含集合sss的段匹配了多少個點。

如果fs<∣s∣×kf_s<|s|\times kfs?<s×k就無解了,然后fsf_sfs?要用高維前綴和或者FWTFWTFWT做就好了。

時間復雜度O(2nnlog?nk)O(2^nn\log nk)O(2nnlognk)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=18; ll n,k,a[N],bit[1<<N],f[1<<N],s[N*200000]; bool check(ll t){ll MS=(1<<n);memset(f,0,sizeof(f));for(ll i=1;i<=t;i++)f[MS-1]++,f[s[i]^(MS-1)]--;for(ll i=0;i<n;i++)for(ll j=0;j<MS;j++)if(j&(1<<i))f[j^(1<<i)]+=f[j];for(ll i=0;i<MS;i++)if(f[i]<bit[i]*k)return 0;return 1; } signed main() {scanf("%lld%lld",&n,&k);for(ll i=0;i<n;i++)scanf("%lld",&a[i]);ll MS=(1<<n),L=2*n*1e5;for(ll i=1;i<MS;i++)bit[i]=bit[i-(i&-i)]+1;for(ll i=1;i<=L;i++)for(ll j=0;j<n;j++)if((i-1)%(a[j]<<1)<a[j])s[i]|=(1<<j);ll l=1,r=L;while(l<=r){ll mid=(l+r)>>1;if(check(mid))r=mid-1;else l=mid+1;}printf("%lld\n",l);return 0; }

總結

以上是生活随笔為你收集整理的ARC106E-Medals【hall定理,高维前缀和】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。