2019 11 12 CSP模擬賽 考前小總結

2022-05-23 08:21:12 字數 4707 閱讀 4811

離聯賽只有幾天了,也馬上就要回歸文化課了。

有點捨不得,感覺自己的水平剛剛有點起色,卻又要被抓回文化課教室了,真想在機房再賴幾天啊。

像19/11/11那場的簡單題,自己還是能敲出一些比較穩的暴力,雖然不見得能拿很高檔的暴力或者打出正解,但至少不會掛分,最後能拿到的分數也還能看。但是一上點難度,或者不對胃口,就明顯感覺力不從心。總是只能打最低檔的暴力,甚至有些題只能拿\(10pts\)的\(dfs\)分。有優化想不出來,有式子也推不出來。時間也總是不夠用——在某道題上浪費了太多時間,最後剛剛推出一點接近正解(或者更高分的暴力)的結論就要考試結束了。

真是菜的令人髮指……= =

講實話,我從來不是什麼很強的選手,甚至可能就中下而已。每場考試也不奢望能想到什麼正解,只求能多拿一點分是一點分,把自己能想到的暴力穩穩當當地敲出來,不要犯什麼低階錯誤就謝天謝地(其實以我的水平,也沒有什麼資本犯低階錯誤吧(苦笑),運氣好的話,能推出一些特殊性質的部分分(然後再超常發揮地把它們敲出來?),不求考得多好,只求不要掛太難看……

最後這麼幾天攻難題似乎也沒什麼太大意義,把任務計畫清理一下,然後打一打之前一直不熟悉的模板。一直逃避的高精,死活想不到狀態的狀壓,因為已經死了所以沒怎麼用過的spfa,沒在考場上打過的主席樹和平衡樹,還有因為考的不多根本沒怎麼寫過的字串演算法……至於剩下的,也只能順其自然了。

懶得放題面了,自己找\(pdf\)吧

我們知道\(string\)的排序是按字典序來比較的,這決定了在一堆字串排完序之後兩個字串越接近,公共字首長度就越長(即他們越相似),那麼直接排完序之後每次抓乙個不在自己位置上的,和它該在的位置上的字串交換一下並記錄方案即可

**:

#include#include#include#include#pragma gcc optimize(2)

#define n (1000000 + 10)

using namespace std;

int n, cnt;

int rk[n];

string s[n];

int pos[n];

struct node2 ope[n];

inline bool cmp (int a, int b)

int main()

} cout << cnt << '\n';

for (register int i = 1; i <= cnt; ++i) cout << ope[i].x << " " << ope[i].y << '\n';

return 0;

}

二分+主席樹驗證

此題的\(trick\)有學習意義,\(kma\)太菜了並沒有見過

暴力分可以貪心,發現顯然只有最大的乙個對答案有影響,所以每次抓最大的來減即可

正解二分一下最終答案\(len\),每秒減少的值並不是問題,在\(check\)的時候把這個量加上去就行

考慮\(check\)在\(s\)次以內能不能把所有小麥值操作到\(len\)以下

首先我們需要\(check\)的只有\(a_i > len\)的,因為剩下的對答案沒影響

那麼我們最終的操作次數\(times = \sum\limits_\lceil\frac\rceil\)

發現這個式子並不好維護到單次查詢\(o(logn)\)的複雜度,也不能直接強拆,考慮巧妙地拆開分別維護

定義\(\)表示實數\(a\)的小數部分

將上式變形得到

\[\begintimes &= \sum\limits_\lceil\lfloor\rfloor + \\} - \lfloor\frac\rfloor-\\}}\rceil \\ &= \sum\limits_\lceil(\lfloor\rfloor - \lfloor\frac\rfloor ) + (\\} - \\})}\rceil \\ &= \sum\limits_\\rfloor - \lfloor\frac\rfloor ) + \lceil (\\} - \\})}\rceil\} \\ &= \sum\limits_\\rfloor - \lfloor\frac\rfloor ) + [(a_i\ mod\ x) > (len\ mod\ x)}]\} \end

\]對於每一坨,我們看看都能怎麼搞

\(\sum\limits_ \lfloor\frac\rfloor\)在\(a_i\)排序之後是乙個字尾和的形式,預處理之後每次詢問二分找一下這個點,\(o(logn)\)

\(\sum\limits_ \lfloor\frac \rfloor\)是乙個常量乘上累加的個數,假設上面二分找到的端點是\(k\),那麼它等價於\((n - k + 1) * \lfloor\frac\rfloor\),\(o(1)\)

\(\sum\limits_[(a_i\ mod \ x) > (len\ mod\ x)]\),發現這實際上是乙個字尾意義上的區間查詢某乙個數的\(rank\),對\(a_i\ mod\ x\)離散化一下建一棵主席樹之後在上面查詢\(len\ mod\ x\)的排名即可,\(o(logn)\)

容易發現對於每次二分的\(check\),我們做到了\(o(logn)\)的複雜度,再加上前面的排序離散化之類的預處理,總複雜度為\(o(nlogn + mlog^2n)\)

**:

#include#define ll long long

using namespace std;

inline ll read()

while (isdigit(c))

return cnt * f;

}const int n = (int)1e5 + 5;

int n, m, rt[n];

ll x, t[n], sum[n], b[n], sz, cnt, lim, s, nx;

void pre_work()

struct node tree[n * 32];

inline int _copy (int u)

void insert(int &p, int l, int r, int pos)

int query(int pos, int l, int r, int x)

bool ck(ll len, ll s)

ll binary(ll l, ll r)

return l;

}int main()

for (register int i = 1; i <= m; ++i) s = read(), printf("%lld\n", binary(0, lim - s));

return 0;

}

組合計數

總共有\(n-1\)個位置可以填+

對於每個\(a_i\)的貢獻分別計算,考慮\(a_i\)之後離它最近的+在**,因為這決定了\(a_i\)最後對於答案的貢獻需要給\(a_i\)乘上乙個\(base\)的多少次方(\(10^i\))

如果+在\(a_i\)之後, 那麼還剩下\(n - 2\)個空位可以填,還剩下\(m - 1\)個+號,\(a_i\)的貢獻是\(a_i * c_^\)

如果+在\(a_\)之後,那麼還剩下\(n - 3\)個空位可以填,還剩下\(m - 1\)個+號,\(a_i\)的貢獻是\(a_i * 10^ * c_^\)

\(\cdots\)

如果+在\(a_\)之後,那麼還剩下\(m - 1\)個空位可以填,還剩下\(m - 1\)個+號,\(a_i\)的貢獻是\(a_i * 10^ * c_^\)

\(a_\)之後是能放的最後乙個位置,因為如果再往後的話,其他+會有堆在一起或出現在開頭結尾的情況(空位不夠)

對於+在\(a_n\)之後的情況單獨討論,這種相當於\(a_i\)存在於最後乙個整數中,那麼還剩\(i - 1\)個空位可以填,\(m\)個+,此時\(a_i\)的貢獻是\(a_i * 10^ * c_^m\)

全部求和,暴力的複雜度是\(o(n^2)\)

發現對於每個乘\(10^k\)的\(a_i\),它們要乘的\(10^k\)是一樣的,並且它們是連續的,考慮字首和優化到\(o(n)\)

最後的柿子是$$\sum\limits_^10^i * (\sum\limits_^ a_j * c_^ + a_ * c_^m)$$

其中\(\sum\limits_^a_j\)需要處理乙個字首和

#include#define ll long long

#define int ll

using namespace std;

inline int read()

while (isdigit(c))

return cnt * f;

}const ll mod = 998244353;

const int n = (int)1e6 + 5;

int n, m;

char x;

ll sum[n], fac[n], inv[n], a[n], ans;

ll mul (ll a, ll b)

ll add (ll a, ll b)

ll qpow(ll a, ll b)

void pre_work()

ll c(ll m, ll n)

signed main()

printf("%lld", ans);

return 0;

}

CSP模擬賽 方程(數學)

題目描述 求關於x的方程 x1 x2 xk n的非負整數解的個數。輸入格式 僅一行,包含兩個正整數n,k。輸出格式 乙個整數,表示方程不同解的個數,這個數可能很大,你只需輸出mod 20080814 的結果。輸入樣例 1 1輸出樣例1提示 資料範圍 對於50 的資料,n,k 300 對於80 的資料...

CSP模擬賽 方程(數學)

求關於x的方程 x1 x2 xk n的非負整數解的個數。僅一行,包含兩個正整數n,k。乙個整數,表示方程不同解的個數,這個數可能很大,你只需輸出mod 20080814 的結果。1 11 提示資料範圍 對於50 的資料,n,k 300 對於80 的資料,n,k 1000 對於100 的資料,n,k ...

CSP模擬賽 巨神兵

題目 歐貝利斯克的巨神兵很喜歡有向圖,有一天他找到了一張 n 個點 m 條邊的有向圖。歐貝利斯克認為乙個沒有環的有向圖是優美的,請問這張圖有多少個子圖 即選定乙個邊集 是優美的?答案對 10 9 7 取模。對於40 的資料 n 5,m 20 對於60 的資料 n 10 對於80 的資料 n 15 對...