離聯賽只有幾天了,也馬上就要回歸文化課了。
有點捨不得,感覺自己的水平剛剛有點起色,卻又要被抓回文化課教室了,真想在機房再賴幾天啊。
像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 對...