CF1178比賽題解

2022-05-05 19:39:10 字數 3568 閱讀 6366

a題

小學抽屜問題,

答案就是\(max(n - s,n - t) + 1\)

複雜度\(o(t)\)

**:

#include int t, n, m, i, j, k;

int a[2];

int main()

}

b題

我們維護乙個\(vector\)陣列\(v\),其中\(v_i\)存的是字母\(i\)所出現的位置。

那麼因為我們是依次\(\text\)的,

那麼第\(i\)個字母的位置其實就是\(v_\)(因為下標從0開始)。

我們查的時候只需要將\(t_i\)遍歷一遍然後取個\(max\)就好。

而訪問乙個下標又是\(o(1)\)的操作,

所以總複雜度為\(o(m * max(|t_i|)\)

**:

#include const int maxn = 2e5 + 10;

const int maxm = 5e4 + 10;

inline void cmax(int& x,int y)

char s[maxn];

int n, m, i, j, k;

int cnt[27];

std::vectorv[27];

int main()

scanf("%d",&m);

while(m--)

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

}return 0;

}

c題

我們把所有操作全部分離,

然後排個序。

然後先處理不下降的,

賦值的時候如果左端點沒有賦值過那就去\(n - x\)(一定保證小於左邊乙個),

否則就使用上一次的賦值(排過序,所以一定不降)。

剩下的如果有空隙那就表示一定是下降序列,

那麼直接填就好。

於是這道題就做完了。

複雜度\(o(n)\)

#include const int maxn = 1010;

const int maxm = 1010;

const int inf = 0x3f3f3f3f;

templateinline void read(tp& res)

inline void cmin(int& x,int y)

inline int _abs(int x)

int n, m, i, j, k;

int a[maxn];

std::vector> q1, q2;

int main()

std::sort(q1.begin(),q1.end());

std::sort(q2.begin(),q2.end());

int v;

for(auto i : q1)

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

if(!a[i])

a[i] = n - i;

for(auto i : q2)

if(!ok)

return puts("no"), 0;

}

puts("yes");

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

printf("%d ",a[i] + 5010);

return 0;

}

d題

又是一道典型的惡意評分。

我們思考一下氣泡排序的原理,每次只對兩個數進行操作可以有同樣的效果。

這時可以發現一點,對於乙個\(a_i\),它一定要比前面的都小才可能到達指定的位置上去。

那麼我們用線段樹維護一下最小值就結束了...

結束了?對,結束了...

複雜度\(o(n log n)\)

**:

#include const int maxn = 3e5 + 10;

const int inf = 0x3f3f3f3f;

templateinline void read(tp& res)

inline int _min(int a,int b)

inline void cmin(int& a,int b)

inline void cmax(int& a,int b)

int n, m, i, j, k, t, mx;

int a[maxn], b[maxn], c[maxn], pos[maxn], t[maxn << 2];

std::queueq[maxn];

inline bool check()

inline void push_up(int u)

void build(int l,int r,int u)

int query(int ql,int qr,int l,int r,int u)

void modify(int m,int l,int r,int u,int v)

int main()

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

read(b[i]), cmax(mx,b[i]), c[ b[i] ]--;

if(!check())

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

q[ a[i] ].push(i);

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

build(1,n,1); bool flag = 1;

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

modify(p,1,n,1,inf);

}if(flag)

puts("yes");

}return 0;

}

e題

樹形dp。

設u為當前節點,

則\(f[fa_u] = s_ + sz_ + n + s_\)

\(f[u] = s_ + 2 * n - sz_u + s_\)

可以推出\(f[u] = f[fa_u] + n - sz_u * 2\)

轉移即可,

#include typedef long long ll;

const int maxn = 2e5 + 10;

int cnte, n, m, i, j, k;

int sz[maxn], hd[maxn], ver[maxn << 1], nxt[maxn << 1];

ll f[maxn], ans;

inline void adde(int u,int v)

inline void cmax(ll& a,ll b)

void dfs1(int u,int pa)

f[1] += sz[u];

}void dfs2(int u,int pa)

}int main()

dfs1(1,0);

dfs2(1,0);

printf("%lld\n",ans);

return 0;

}

3 6CF1114比賽補題

b 排序 貪心 首先想到,選擇的mk個數字一定是最大的,因為無論如何分組,總有區間是包含前mk大的數字的。然後是分組,分組的情況不是唯一的 開始的時候分組一直和樣例不一樣,改了好多次 後來發現分組可以不一樣qaq include include include include include inc...

題解 CF1119H Tripe題解

題目傳送門 給出 n,t,x,y,z 值域 le 2 t 給出 n 個三元組 a i,b i,c i 表示有 x 個 a i y 個 b i z 個 c i 對於每個 k in 0,2 t 1 求出從每組選出乙個數的異或值為 k 的方案數。先定義 delta n f delta 表示多項式 f 的第...

題解 CF1485 簡要題解

奇怪的難度。當 b 2 的時候再操作,操作次數是一定的。因此 b 的變化量很小,暴力列舉。考慮哪個數不同,然後不同後可以選擇的區間是什麼。會發現中間夾著的區間選兩遍,旁邊的選一遍。做字首和好了。簡單轉化發現一定要滿足 a k b 1 k。列舉 b 貢獻式帶有乙個 min 找到其分割點,前一部分直接求...