洛谷P5652 基礎博弈練習題

2022-03-16 23:32:40 字數 1266 閱讀 8201

cjr orz

設\(f_i\)表示第乙個到\(i\)的人是否必勝,對於詢問\([l,r]\),可以發現\(f_r\)只與\(a_r\)的奇偶性有關,奇數為1偶數為0

如果\(f_i=1\),那麼\(i\)向前\(m\)位都有\(f_j=0\),對於點\(i-m-1\),如果有人到這裡無路可走,他就必須向後走,一定會落到這\(m\)個位置之一中,即必輸,所以\(f_\)的勝負也只與\(a_\)的奇偶性有關

如果\(f_i=0\),考慮\(f_\),如果\(a_\)為偶數,假設\(b_=2\)去試,如果a走進來,那麼b可以不走出去,那麼只能a走出去,但是後面能到達的點一定都是0(否則為什麼\(f_i\)會為0),所以\(f_=0\),奇數亦然;綜上,\(f_\)的勝負與\(a_\)奇偶性相關

將\(i\)作為右邊界時,用上面兩項可以推出此時它前面有哪些為1,將它和最近的1連邊,沒有就向0節點連邊,每個點都會向前面乙個點連邊,顯然會構成乙個樹形結構,乙個點只有父親節點都是必勝節點

判斷\([l,r]\)是否必勝,等價於判斷\(l\)是不是\(r\)的父親,用dfs序即可,注意特判\(l==r\)

#include#define n 2000005

#define re register

using namespace std;

typedef long long ll;

int n,m,q,a[n],pre[n],type;

int size[n],dfn[n],c;

const ll mod = 4294967296;

templatevoid read(t &x)

struct edge

edge[n];int head[n],cnt=1;

void add_edge(int from,int to)

ll a,b,c,p;

inline int rnd()

void dfs(int rt)

}void init()

for(re int i=1;i<=n;++i)

int x=i-m-1;

if(x>0) add_edge(pre[x],i);

else add_edge(0,i);

} dfs(0);

}inline bool query(int x,int y)

int main()

} else }

cout<<(ans%mod+mod)%mod

}

LuoguP5652 基礎博弈練習題 博弈

歸納 找規律.如果終點 r 是奇數,那麼 r m 1 r 1 這段區間都是先手必敗.然後我們發現 r m 1 及之前都是偶數的話還是先手比敗,直到遇到乙個奇數,就又變成了先手必勝.那麼,對於乙個奇數字置,其前面第乙個先手必勝位置就是 r m 1 前第乙個奇數字置.對於偶數,我們發現是先手必敗,而其前...

洛谷練習題1 2

分段函式 include using namespace std intmain if k 151 sum sum 0.4463 k sum int sum 10 0.5 sum sum 10 cout 簡單的判斷 include using namespace std intmain cout 注...

洛谷 P1957 口算練習題

並不難的一條題目 就幾個點要注意 1.計算數字的長度時 要記得可能有負數 對負數要特殊處理 2.對於這種不是很難 操作卻略繁瑣的題目 要先將每一步在草稿紙上分析好 再寫 以便保持思路的清晰 特別是我這種思維混亂的人 p1957 口算練習題 include include include includ...