【考試反思】聯賽模擬測試15 To be continued
阿新 • • 發佈:2020-10-13
建議改成:凱爹吊打 std
。
凱爹被卡常了,可惡啊。
基礎篇,但成功暴露了基礎很薄弱。T4 LCIS 完全沒思路。
T1: 90 \(\rightarrow\) 80
T1:遊戲
對自己暴力太自信了,想資料點分治,但顯然 \(O(10!\cdot 10)\) 顯然是跑不過 500ms
的。= =
其實也不好意思說是掛分,因為是亂搞的水了很多分。對拍大概每 3000,4000 組就掛了,但是資料太水,就很偷稅
正解是和之前的哪一天她能重回我身邊類似,但沒有疾患鼠的情況所以更簡單。同樣兩個值連邊,統計聯通塊大小。
T2:嘟嘟嚕
約瑟夫問題,但顯然線性是過不去的。
打表發現(建議 \(m\) 取 4,很容易找到規律),只有過了一段區間之後才會出現取模的情況,那就是目前的值比下標大的時候。那麼我們顯然可以計算出下次跳到需要取模的位置。
設下一次需要跳 \(x\) 步,目前的值是 \(a\),那麼可以得到:
\[i+x<a+m\times x \]首先注意一定是小於,因為正好相等的時候是不能取模的,因為實際上正好相等的時候對應到 \(0\)~\(n-1\) 的編號是比下標小的。
簡單移項改等號解得:
\[x=\bigg\lceil \cfrac{i-a}{m-1} \bigg\rceil \]那麼下次的下標就是 \(i+x\)。相等的時候需要特判一下,懂的都懂。
最後剩下的部分直接加上就好了。小於 \(m\) 的部分直接暴力。
時間複雜度 \(O(能過)\)。
當然前提是你要會線性解決約瑟夫問題的式子,可以看前幾天的拿道題。
Code
#include <bits/stdc++.h> using namespace std; inline int read(){ int x=0;bool fopt=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=0; for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48; return fopt?x:-x; } int main(){ #ifndef LOCAL freopen("mayuri.in","r",stdin); freopen("mayuri.out","w",stdout); #endif int T=read(); while(T--){ int n=read(),m=read(),x=0,i=m; for(register int j=2;j<=min(n,m);j++){ x=(x+m)%j; } if(n<=m)printf("%d\n",x+1); else{ x+=1;//記得+1! while(1){ int nxt=i+(int)ceil(1.0*(i-x)/(m-1)); if(nxt>n)break; x=(x+(nxt-i)*m); if(x==nxt){ if(++nxt>n)break; x=(x+m)%nxt; }else x%=nxt; i=nxt; } x+=(n-i)*m; printf("%d\n",x); } } return 0; }
T3:天才紳士少女助手克里斯蒂娜
好像直接改改式子,就能用線段樹區間加區間求和了。但是 T2 調了太久,所以本題 10 min 走人= =。
T4:鳳凰院凶真
LCIS 並輸出方案,爺不會(wtcl)。