【題目描述】
有 n 堆石子,第 i 堆有 xi 個。
alice 和 bob 輪流取石子(先後手未定),alice 每次從一堆中取走 a 個,bob
每次從一堆中取走 b 個,無法操作者輸。
不難發現只會有四種情況:alice 必勝;bob 必勝;先手必勝;後手必勝。
你需要選定若干堆石子(共有 2^n 種方案),alice 和 bob 只能在你選出的堆
中取,問以上四種情況對應的方案數。
【輸入資料】
第一行三個整數 n,a,b,第二行 n 個整數 x1~xn。
【輸出資料】
一行四個整數,分別表示 alice 必勝、bob 必勝、先手必勝和後手必勝的方
案數,對 10^9+7 取模。
【樣例輸入】
2 2 3
2 3【樣例輸出】
2 0 1 1
【樣例解釋】
選定空集時後手必勝,選定時 alice 必勝,選定時先手必勝,選定時 alice
必勝。【資料範圍】
對於 10%的資料,n,xi<=5。
對於 50%的資料,n<=20。
對於另外 10%的資料,a=b。
對於又另外 20%的資料,a=1。
對於 100%的資料,1<=n<=100000,1<=a,b,xi<=10^9。
首先我們可以把每堆石子的個數mod(a+b)
這是從博弈學的平衡性(我自己取的名)入手的
下面是個人見解,正確性unknown
首先,這樣想一場遊戲,只有一堆石子
你取了a個,對方緊跟著你在同一堆取了b個,
一輪減少(a+b)個 ,其實無論經過多少輪結果都是一樣的。
該輸的照樣輸,該贏的照樣贏
那麼就把個數mod(a+b)不就好了?
如果有多堆的話,一人突然對另外一堆來操作
這時,另一人會緊跟前一人去同樣的堆操作
且在前一人重新對原來的堆操作之前,也不對前一堆操作
這樣,其實第一人只是將操作推後了而已,他還是要操作的。
那麼,為啥另一人會跟著呢?
因為前一人換堆肯定是因為他不換就會輸
後一人就會贏,所以後一人這樣就可以將前一人鎖定在必輸的情形,這是出於最佳策略
就像那個多個遊戲的和什麼什麼的。。。。。
然後對於所有的堆分類討論即可,
::stone:
不妨假設a每堆石子先對a+b取模,然後可以分為4種:
(1) xi(2) a<=xi,只要存在則a必勝。
(3) b<=xi<2a,只和奇偶性有關。
(4) 2a<=xi,存在至少2個則a必勝,存在1個且(3)為偶數則先手必勝,存在1個且(3)為奇數則a必勝,不存在且(3)為奇數則先手必勝,不存在且(3)為偶數則後手必勝。
注意,在n個物品中選出奇數個物品的方案數為2^(n-1)
(或偶數個物品)
看看楊輝三角就知道 了。
另外這個題將無石子歸為後手贏,相當於強行定義c(0,0)=1,這不僅讓楊輝三角失去了樸素的美感,還讓**擠滿了醜惡的三目運算子。
accode:
//神之技巧:σc(n,k)=2^(n-1) 其中k為都奇數,或都為偶數,可以從楊輝三角上直觀的證明
/*0:無關
1:b>=u>=a 有則a必勝 因為a可以把這堆屯著,b管不著
然後是重要的兩點
i:如果2*a>b
那麼一堆石子滿足b<=u<2*a
雙方只要有乙個人拿了一次,就會使它廢為第0類,成為爭奪的重點,有奇數個則先手贏,否則後手贏
一堆石子滿足 u>=2*a>b
那麼a只要拿一次就可以把它轉化為1然後勝利
所以b的唯一機會就是先手(搞掉唯一的一堆),
所以這樣的石子有兩堆則a必贏
有一堆則b可能贏(把這堆破壞會浪費b的先手條件,看奇偶)。
無則看奇偶
ii:如果2*a<=b
那麼a<=2*a<=b
無異於1
u>=b時看奇偶
*/#include#include#include#include#define mod 1000000007
#define maxn 100005
#define ll long long
using namespace std;
ll n,a,b;
bool rev;
ll pow(int base,int k)
int main(),ans[5]={};
for(int i=1;i<=n;i++)
ll inc=pow(2,cnt[0]);//最後計算
ans[0]=((pow(2,cnt[1])-1)*pow(2,cnt[2]+cnt[3])%mod+(pow(2,cnt[3])-cnt[3]-1)*pow(2,cnt[2])%mod+cnt[3]*(cnt[2]?pow(2,cnt[2]-1):0)%mod)%mod;
//ans[1]=0;
ans[2]=((cnt[2]?pow(2,cnt[2]-1):0)+(cnt[2]?pow(2,cnt[2]-1):1)*cnt[3]%mod)%mod;
ans[3]=(cnt[2]?pow(2,cnt[2]-1):1);
for(int i=0;i<4;i++)
ans[i]=(ans[i]*inc)%mod,
ans[i]=(ans[i]+mod)%mod;
if(rev) swap(ans[0],ans[1]);
printf("%lld %lld %lld %lld\n",ans[0],ans[1],ans[2],ans[3]);
}
雅禮國慶集訓
灑落君臣契,飛騰戰伐名。杜甫 公安縣懷古 noip 前的乙個月。這浸滿熱血的虔信,真的會化作墓碑嗎?或許明日我們不再是戰友,但人生終將有無數個此時。define f z,u,v for int z u des z v z des z z struct bnd struct tup template ...
雅禮集訓 2017 價
傳送門 乙個不太顯然的最小割做法。我們這麼連邊 源點向藥物連 infty p i 容量的邊,藥物向它對應的藥材連 infty 容量的邊,藥材向匯點連 infty 容量的邊。用源點的流量減去最小割,再負回來就可以求出答案了。怎麼理解呢?割掉一條邊表示不選其對應的藥物或藥材,我們發現最後的方案一定是完美...
雅禮集訓 2017 Day2 線段遊戲
記憶體限制 256 mib 時間限制 1000 ms 標準輸入輸出 題目型別 傳統 評測方式 special judge 上傳者 匿名 題目描述 給出若干條線段,用 x1,y2 x2,y2 表示其兩端點座標,現在要求支援兩種操作 輸入格式 第一行兩個正整數 n m 為初始的線段個數和操作個數。接下來...