CEOI2020 象棋世界

2022-05-20 04:56:30 字數 3819 閱讀 1657

下文預設\(n=r,m=c,x=c_1,y=c_r\)略略

先判掉一次到達的情況,然後就可以從起點和終點分別畫出5條可行線

由此得到若干交點,手動數一下有幾個交點在內部的整點上

void qqq()

if(((x+1)&1)==((y+n)&1))

printf("%d %d\n",2,res);

}}

\[\

\]\[\

\]看起來是很複雜的問題,但是實際上可以從乙個簡單的貪心入手

判定條件

可以發現,任意一次行走的直線上,座標\((x,y)\)的\((x+y)\mod 2\)不變

所以只要\(x+1\equiv y+n\pmod 2\)即可

貪心策略

首先一定是每次向前走

第一步選擇向左/右,然後每次轉向,每次走都頂到邊界線

但是這樣顯然會無法到達最終位置

糾正方法

考慮貪心到達的最後位置為\(to\),那麼得到的差值\(|to-y|\)是我們要矯正的距離

而矯正方法:在中途出現的每次轉向位置,向裡面"凹"進去一點,每凹進去一格,實際上相當於少走了兩格

注意矯正的方向是根據最後一步走的方向而變化的,因此如果矯正方向不對,需要額外增加一步

此時,相當於需要多矯正到沿邊界線對稱的位置,需要多走\(2(to-1)\)或者\(2(m-to)\)的距離

假設走了\(c\)步,那麼我們有\(c-1\)個轉折點,最後將這若干的矯正距離分配到\(c-1\)個轉折點上,可以用乙個組合數解決

由於矯正距離是\(o(m)\)的,所以組合數顯然可以在\(o(m)\)時間內求出

\[\

\]最後將向左向右合併即可

ll qpow(ll x,ll k=p-2) 

int c(int n,int m)

int divide(int n,int m)

void bbb()

\[\

\]\[\

\]可以發現,每次一定是向前的三個方向走,由此可以得到乙個簡單的$o(nm)\ $ \(dp\)

用矩陣優化可以做到\(o(m^3\log n)\)求出所有的答案

難點在於如果快速求出這個矩陣\(a\)的\(a^\),即要加速矩陣求冪

容易想到用特徵多項式解決該問題,參考

問題分為兩步

得到\(p_m(\lambda)\)

列出我們的轉移矩陣\(a=\)

\(\begin1\ 1\ 0\ 0\ 0\ 0\ \cdots \ 0\\ 1\ 1\ 1\ 0\ 0\ 0\ \cdots \ 0\\ 0\ 1\ 1\ 1\ 0\ 0\ \cdots \ 0\\ \cdots\cdots\cdots\cdots \\ 0\ \cdots\ 0\ 0\ 1\ 1\ 1\ 0\\0\ \cdots\ 0\ 0\ 0\ 1\ 1\ 1\\ 0\ \cdots\ 0\ 0\ 0\ 0\ 1 \ 1\end\)

\(\lambda i-a=\)

\(\lambda -1\)

\(-1\)

\(0\)

\(0\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(-1\)

\(\lambda -1\)

\(-1\)

\(0\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(0\)

\(-1\)

\(\lambda -1\)

\(-1\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(\cdots\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(-1\)

\(\lambda -1\)

\(-1\)

\(0\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(0\)

\(-1\)

\(\lambda -1\)

\(-1\)

\(0\)

\(0\)

\(\cdots\)

\(0\)

\(0\)

\(0\)

\(-1\)

\(\lambda -1\)

每一行有\(2/3\)個元素,看起來並不是很好得到行列式

但是容易得到乙個遞推式,設\(m\)階轉移矩陣的特徵多項式為\(p_m(\lambda)\)

如果最後一行取第\(m\)個元素,值為\((\lambda-1)p_(\lambda)\)

如果最後一行取第\(m-1\)個元素,值為\(-p_(\lambda)\)

因而得到

\(p_m(\lambda)=\left\1&& m=0\\ \lambda-1 && m=1\\ (\lambda-1)p_(\lambda)-p_(\lambda) && m>1\end\right.\)

可以在\(o(m^2)\)的時間內暴力求出,也可以得到通項公式(太憨了)

那麼得到關係用\(\lambda^n\mod p_m(\lambda)\)的係數優化計算,可以用暴力實現的多項式取模+快速冪得到\(o(m^2\log n)\)

當然也可以優化

\[\

\]求出\(a^0,a^1,a^2\cdots a^m\)

直接求顯然是\(o(m^3)\)的,卡一卡說不定能過?

由於走的是乙個\(m\times m\)的棋盤,可以用乙個簡單容斥得到答案

設\(f_\)為從\(x\)走到\(y\),中途允許超出邊界的方案數

由於棋盤只有\(m\times m\),中途最多隻會可能經過一條邊界線

而一旦在某乙個時刻超出邊界線到達\(0/m+1\),那麼接下來達到這條邊界線兩側對稱點的方案數是一樣的

即:跨過了某一條邊界線\(0/m+1\)的不合法方案數,可以用到達\(y\)關於這條邊界線的對稱點的不一定合法方案數得到

而不一定合法的\(f_\)實際上只和\(|x-y|\)有關

由此,可以用\(f_\)表示出\(a^i_\),那麼接下來只需要先計算出\(f_\)對於係數的求和,最終進行一次容斥,減去兩側不合法方案數即可

typedef vector poly;

poly operator * (const poly &a,const poly &b)

poly operator * (poly a,const int &b)

poly operator + (poly a,const poly &b)

poly f,g,t=poly;

int f[n*2],g[n*2],h[n*2];

void kkkinit(),f=t;

rep(i,2,m) swap(f,g),f=g*t-f; // 遞推特徵多項式

f=pow(poly,n-1,f); // 求出x^ mod p(x)

f[0]=1,h[0]=f[0];

rep(t,1,f.size()-1) ,只需要求一半

rep(i,0,t) g[i]=f[i];

rep(i,0,t) }}

void kkk()

CEOI2015 Day2 世界冰球錦標賽

題目描述 譯自 ceoi2015 day2 t1 ice hockey world championship 今年的世界冰球錦標賽在捷克舉行。bobek 已經抵達布拉格,他不是任何團隊的粉絲,也沒有時間觀念。他只是單純的想去看幾場比賽。如果他有足夠的錢,他會去看所有的比賽。不幸的是,他的財產十分有限...

科幻世界2023年增刊簡評

感覺自己很久沒有認真看過科幻世界了,下決心看完增刊後想不負責任地點評一二,有不同觀點還請輕噴。通篇看下來感覺還是索大的風格,選材用了比較經典的編中國神話故事,基本上就是從一些有名的文言文裡拿出幾句話,編點高科技然後讓角色說點黑話把大家熟知的高科技概念換個方式說。不過索大一向好萊塢故事大片講的比較厲害...

完美世界發布2020業績預告 遊戲淨利潤預增20

1月29日,a股遊戲板塊龍頭公司完美世界發布2020年度業績預告。期內遊戲業務預計實現淨利潤22.7 22.9億元,同比大幅增長19.62 20.67 公司2020年整體預計實現淨利潤15.1 15.7億元,同比上公升0.48 4.47 伴隨2020年遊戲行業整體復甦,完美世界遊戲業務持續增長,移動...