2022 02 06 集訓題解

2022-09-28 04:27:12 字數 2754 閱讀 4567

不難注意到的是,我們假設 \(f_i\) 為 \(i\) 之前 \(\le a_i\) 的值的個數,那麼我們需要滿足:

\[\sum_^ i-f_i=\sum_^ i-\min(i,a_i)

\]又因為我們可以知道 \(f_i\le \min(i,a_i)\),所以我們對於每乙個 \(i\) 都有 \(f_i=\min(i,a_i)\)。

考慮如何構造這樣的 \(a\) 。可以發現,我們選了乙個 \(a_i\) 就將 \(a_i\) 這個位置賦值為 \(1\)。那麼,\(f_i=i\) 就是選乙個比最大值大的值,\(f_i=a_i\) 就是選第乙個空位。

考慮到我們可以用 \((i,v)\) 來表示第 \(i\) 步最大值為 \(v\),那麼找第乙個空位就是向右走一步,找最大值就是向上走若干步。所以答案就是從 \((0,n-\text)\) 出發到 \((n-m,n-m)\),且不能低於 \(y=x\) 這條直線的方案數,直接用卡塔蘭數的方法來就好了。

#include using namespace std;

#define int register int

#define mod 1000000007

#define maxn 200005

template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}

template inline void read (t &t,args&... args)

template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}

template inline void chkmax (t &a,t b)

template inline void chkmin (t &a,t b)

int n,m,a[maxn],fac[maxn],ifac[maxn];

int mul (int a,int b)

int dec (int a,int b)

int add (int a,int b)

int qkpow (int a,int b)

void add (int &a,int b)

void sub (int &a,int b)

struct bit_tree

void modify (int x,int v)

int query (int x)

}tree;

int binom (int a,int b)

signed main()

tot = n - maxv;int all = n - m;

write (dec (binom (all + tot,all),binom (all + tot,all + 1)));

return 0;

}

太水了,懶得說了

有乙個奇怪的貪心,就是說我們一開始先對任意相鄰兩項都移動到中心,直到不能移動為止。然後我們就對最大最小值進行操作,可以讓他們兩個向中間動乙個,但是中間的節點並不改變。

優化的話,可以發現第一步我們可以使用增量法,那麼只需要維護每個斜率為 \(1\) 的段的起點即可,第二步直接左右向中間移動即可。

#include using namespace std;

#define int register int

#define int long long

#define maxn 1000005

#define ll long long

template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}

template inline void read (t &t,args&... args)

template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}

template inline void chkmax (t &a,t b)

template inline void chkmin (t &a,t b)

int n,top,a[maxn],sta[maxn],tot[maxn];

struct bit_tree

void modify (int x,int v)

int query (int x)

void change (int l,int r)

}t;signed main()

if (a[i] != lstv)

} else sta[++ top] = i;

a[i] -= t.query (i);

} for (int i = 1;i <= n;++ i) a[i] += t.query (i),tot[a[i]] ++;

int miv = a[1],mxv = a[n];

while (miv + 1 < mxv)

write (ans),putchar ('\n');

return 0;

}

2022 04 04 集訓題解

小 w 的手上有一顆 n 個節點的二叉搜尋樹,裡面有從 1 到 n 這 n 個數字。二叉搜尋樹即為中序遍歷恰好為 1 到 n 的二叉樹 現在你想知道這棵樹的形態。但是小 w 不會直接告訴你,只允許你詢問以某個點為根的子樹是否恰好包含 l,r 中的所有點。你需要在 2 times n 次查詢之內得到整...

2020 08 18 集訓題目題解

講數字dp,然後發現自己學暴了,這裡挑幾道有意思的題目記錄一下,以免將來死得太慘。題目傳送門 定義 windy 數為滿足相鄰兩位差值 le 2 的數,給出 l,r 求出 l,r 內有多少 windy 數。l,r le 2 times 10 9 我 這樣乙個板子題調了乙個小時,果然是我自己菜爆了。我們...

2020 08 05 集訓題目題解

題目傳送門 給出乙個長度為 n 的數列 a 有 m 次操作,每次操作分別為以下兩種 n,m le 5 times 10 4 其實我們可以發現乙個事情,最後 c bmod varphi 1 varphi 1 bmod varphi p varphi p 然後我們就發現到了一定程度之後再加上 c 都不會...