PKUSC2018 真實排名

2022-05-19 21:36:11 字數 1273 閱讀 2413

對每個數,先分類討論,將答案分為這個數有翻倍和這個數沒翻倍。

在討論前,我們規定:\(low(x)\)為小於等於這個數的數的個數,當前數為\(x\)。

如果這個數沒翻倍:我們考慮哪些數翻倍不會影響這個數的排名,一種是翻倍後依然小於\(x\)的,一種是本來就大於等於\(x\)的。

那麼對於第一種情況,情況數為

\[c(low((x+1)/2-1)+n-low(x-1)-1,k)

\](\(c(n,m)\)為組合數,下同)

這裡前面一項最後的減一表示不能選當前數。

如果這個數翻倍了:我們考慮那些數必須翻倍,那些數可以選擇性翻倍。

必須翻倍的數就是為了維持原排名所需翻倍的數,就是小於\(2x\)同時大於等於\(x\)的所有數。

選擇翻倍的數就是翻倍後不會影響當前排名的數,就是小於\(x\)的數和大於等於\(2x\)的數的數。

這裡要注意,如果必須翻倍的數大於\(k\)那麼在這種討論中就不可能有情況滿足當前數排名不變。

設必須翻倍的數為\(js=low(2x-1)-low(x-1)\),那麼對於第二種情況,情況數為

\[c(n-js,k-js)

\]那麼答案就是兩者相加了。

#includeusing namespace std;

const int n=100010,p=998244353;

int add(int x,int y)

int mul(int x,int y)

int n,k;

int a[n],b[n];

int fac[n],inv[n];

int c(int n,int m)

int mpow(int a,int n)

return ret;

}int low(int x)

int main()

sort(b+1,b+n+1);

b[0]=-1e9+7;

b[n+1]=0x7fffffff;

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

int ret=c(low((a[i]+1)/2-1)+n-low(a[i]-1)-1,k);

int js=low(2*a[i]-1)-low(a[i]-1);

if(k>=js)

printf("%d\n",ret);

}}

PKUSC 2018 真實排名

戳我 我們將現在所要進行的數設為 now 我們分情況討論一下 他自己不翻倍 他自己翻倍 我們首先來看看 1 操作 如果要滿足他對排名沒有影響,那麼不能進行翻倍的數只有 lceil frac rceil,now 我考場上不知道在幹嗎,寫的是能進行翻倍的數,麻煩好多,常數也大 我們假設這一段為 cnt ...

PKUSC2018 真實排名 線段樹 組合數

pkusc2018 真實排名 對於每個數 val 分兩種情況討論 1 當 val 不翻倍時,那麼可以翻倍的是權值比 frac 小的和大於等於 val 的。2 當 val 翻倍時,顯然權值在 val,val 2 1 的都要翻倍,剩下可以翻倍的是權值比 val 小的和大於等於 2 val 的。用權值線段...

P5368 PKUSC2018 真實排名

problem link 對於每個 a i 我們可以考慮這 k 個選手中要不要有 a i 如果沒有的話,那我們就看看有哪些 a j 在翻倍後不會影響到 a i 的排名 顯然 2 a j或者 a i le a j 的這些 a j 都滿足要求,我們記它們的個數為 cnt 1 那麼如果這 k 個中有 a ...