loj 2719 NOI2018 氣泡排序

2022-09-11 02:03:16 字數 1533 閱讀 9472

\(t =5,\sum n \le 2000000\)

考慮什麼樣的排列是好的.為了達到下界,\(p_i\)應該只向\(i\)的方向移動,也就是說,不存在乙個數左右都有逆序對,也就是說,不存在\(a使得\(p_a>p_b>p_c\)

無視\(q\)的限制,可以用dp計算答案,設\(dp(i,j)\)表示確定了排列的前\(i\)個數,設其中最大值為\(mx\),小於\(mx\)的值中有\(j\)個還沒有在排列**現.那麼每次要麼選擇乙個大於\(mx\)的數,要麼將小於\(mx\)的最小的數加入排列

\[f(i,j)=f(i-1,j+1)+\sum_ f(i-1,j-k)

\]初始狀態為\(dp(0,0)=1\),最終答案為\(dp(n,0)\).那麼考慮括號序來表示,每次\(j\)要麼\(-1\),要麼增加乙個非負整數,那麼可以看作加入任意多個左括號後加入乙個右括號(\(-1\)相當於加入0個左括號).

考慮\(q\)的限制,我們可以像數字dp一樣列舉\(p\)在哪個位置字典序第一次大於\(q\).那麼我們可以維護在這個位置之前加入的左括號數.為了使這個位置的數大於\(q_i\),還需要加入適量左括號.於是我們要計算的就是,當前序列有\(cnt\)個左括號,還可以加入\(n-i+1\)個右括號,其中每個右括號前可以增加任意個左括號,這樣的合法括號序個數.

設當前有\(b\)個左括號,還可以加入\(a\)個右括號,那麼一共要加入的括號數就是\(n=2a-b\).考慮折線法,翻轉第一次到達\(y=-1\)直線之前的路徑,那麼所有非法路徑相當於從\((0,-y-2)\)到\((n,0)\)的路徑數.那麼答案相當於

\[\binom nx - \binom n2} = \binom nx - \binom n2+1}

\]注意在列舉字典序第一次大於的位置時注意已經加入的部分是否合法.

#include #include #include #define debug(...) fprintf(stderr,__va_args__)

#define inver(a) power(a,mod-2)

using namespace std;

inline char nc()

templatevoid read(t &x)

while(ch>='0'&&ch<='9')

x*=f;

}typedef long long ll;

const int mod=998244353;

const int maxn=6e5+50;

int t,n,q[maxn];

int fac[maxn<<1],inv[maxn<<1];

bool vis[maxn];

inline int add(int x)

inline int sub(int x)

ll power(ll x,ll y)

return re;

}inline int binom(int x,int y)

int main()

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

} return 0;

}

題解 LOJ2719 NOI2018 氣泡排序

考慮乙個排列的交換次數何時會超過下界。以題目中的 3 2 1 為例,在把 3 向後移時 2 被向前推了一次,在把 1 向前移時 2 又被向後推了一次。這樣一來一回,就產生了無效操作。於是我們發現,乙個排列是好的,當且僅當在氣泡排序的過程中,不存在某個元素同時做了兩個方向的移動 這樣必然產生 一來一回...

NOI2018 氣泡排序

noi2018 氣泡排序 題解性質 模型轉化 首先,乙個排列是 好 的,當且僅當 每個數,要麼是字首最大值,要麼是字尾最小值。討論i和pi的關係即可證明 也就是,排列不能存在 3的下降子串行!換句話說,假設之前填了i個數,最大值是mx,那麼第i 1個數,要麼是剩下數的最小值,要麼是比mx大的數。字典...

NOI2018 氣泡排序

題面 吐槽 好像發的pdf題面的冒泡是掛掛的,還好我還會氣泡排序 逃 具體思路 首先發現當這個序列的最長下降序列長度大於2時,一定不符合要求 那麼我們可以想出乙個 o n 2 的dp f i,j 表示前 i 個數,設其中最大的數為 mx 後面的數中有 j 個數比 mx 小的方案數 然後發現 f i,...