日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2016-2017 7th BSUIR Open Programming Contest. Final 补题

發(fā)布時間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2016-2017 7th BSUIR Open Programming Contest. Final 补题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接

https://codeforces.com/gym/102133

參考題解

A - Tree Orientation

簡要題意:

給定 nnn 個結點的無向樹,根為 111 號點,問有多少種將邊定向的方案,使得出度為 000 的點恰有 mmm 個。

解題思路:

考慮 dpdpdp,每個結點考慮其到父結點的邊的定向情況,fp[u][i]fp[u][i]fp[u][i] 表示 uuu 子樹內, uuu 結點的邊指向父結點時,恰有 iii 個出度為 000 的點的方案數;同理 fd[u][i][0/1]fd[u][i][0/1]fd[u][i][0/1] 表示將邊指向 uuu 結點,這里需要額外加一維表示 uuu 是否出度為 000。轉移時逐子樹合并轉移,復雜度分析同樹上背包。狀態(tài)轉移見代碼。

參考代碼:
#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e3 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;vector<int> G[maxn]; int siz[maxn]; ll fd[maxn][maxn][2], fp[maxn][maxn]; int n, m;void dfs(int u, int f){siz[u] = 1, fd[u][1][1] = fp[u][0] = 1;for(auto &v : G[u]){if(v == f) continue;dfs(v, u);memset(fd[0], 0, sizeof fd[0]);memset(fp[0], 0, sizeof fp[0]);for(int i = siz[u]; i >= 0; --i){for(int j = siz[v]; j >= 0; --j){(fd[0][i + j][0] += fd[u][i][0] * (fd[v][j][0] + fd[v][j][1] + fp[v][j])) %= mod;if(i + j > 0) (fd[0][i + j - 1][0] += fd[u][i][1] * (fd[v][j][0] + fd[v][j][1])) %= mod;(fd[0][i + j][1] += fd[u][i][1] * fp[v][j]) %= mod;(fp[0][i + j] += fp[u][i] * (fd[v][j][0] + fd[v][j][1] + fp[v][j])) %= mod;}}memcpy(fd[u], fd[0], sizeof fd[0]);memcpy(fp[u], fp[0], sizeof fp[0]);siz[u] += siz[v];} }int main(){ios::sync_with_stdio(0); cin.tie(0);cin >> n >> m;for(int i = 1; i < n; ++i){int u, v; cin >> u >> v;G[u].pb(v), G[v].pb(u);}dfs(1, 0);ll ret = (fd[1][m][0] + fd[1][m][1]) % mod;cout << ret << endl;return 0; }

B - A Masterpiece

簡要題意:

給一個數 nnn,求構造 n×nn×nn×n 的矩陣,滿足數 111n2n^2n2 分別出現(xiàn)一次,并且任意相鄰的數差值大于 111,且任意一組 nnn 個行下標不同、且列下標不同的數之和相同。

解題思路:

n=1n = 1n=1 時單走一個 1112≤n≤32 \leq n \leq 32n3 無解;否則,令 ai,j=(i?1)?n+ja_{i, j} = (i - 1) * n + jai,j?=(i?1)?n+j,則僅不滿足行內相鄰數差值大于 111 這個條件。由和值相同的條件得到任意 ai1,j1?ai1,j2=ai2,j1?ai2,j2a_{i1,j1} - a_{i1, j2} = a_{i2, j1} - a_{i2, j2}ai1,j1??ai1,j2?=ai2,j1??ai2,j2?,故僅需要對列進行交換調整答案,一個可行方案為先排列偶數列、再排奇數列。

參考代碼:
#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e2 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;int n;int main(){ios::sync_with_stdio(0); cin.tie(0);cin >> n;if(n == 1){cout << "1" << endl;cout << "1" << endl;}else if(n <= 3){cout << "-1" << endl;}else{cout << n << endl;for(int i = 1; i <= n; ++i){int x = (i - 1) * n;for(int j = 2; j <= n; j += 2) cout << x + j << " ";for(int j = 1; j <= n; j += 2) cout << x + j << " ";cout << endl;}}return 0; }

C - Auction

簡要題意:

給定一個數 nnn,現(xiàn)有 x=1x = 1x=1ABABAB 兩人輪流對 xxx 乘上 222999 中的一個數,AAA 先手,當 x>nx > nx>n 時停止游戲,無法操作的一方輸。問是否先手必勝。

解題思路:

逆向考慮,當 x>nx \gt nx>n 為必敗態(tài),x∈(?n9?,n]x \in (\lfloor\frac{n}{9}\rfloor, n]x(?9n??,n] 為必勝態(tài)(存在一種 ×9×9×9 的操作使得對方必敗),x∈(??n9?2?,?n9?]x \in (\lfloor\cfrac{\lfloor\frac{n}{9}\rfloor}{2}\rfloor, \lfloor\frac{n}{9}\rfloor]x(?2?9n????,?9n??] 為必敗態(tài)(無論乘上多少對方都落入前面那個必勝態(tài)),以此類推。

參考代碼:
#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e2 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;int main(){ios::sync_with_stdio(0); cin.tie(0);int T; cin >> T;while(T--){ll n; cin >> n;ll l = n / 9, r = n, d = 9, ret = 1;while(l >= 1){d = d == 2 ? 9 : 2;r = l, l /= d, ret ^= 1;// cout << l << " " << r << " " << ret << endl;}cout << (ret ? "YES" : "NO") << endl;}return 0; }

F - Financial Reports

簡要題意:

給一個數組 aaa,求在進行一次交換操作后的最大子段和,并輸出交換方案,交換下標須不同、最大子段和區(qū)間非空。

解題思路:

交換后最大子段和必然不減,若最大子段和不變,如果區(qū)間長為 111,則任意交換都可以成為答案;若區(qū)間長度大于 111,交換最大子段和內部兩個下標。否則,考慮答案有增加的交換操作,考慮枚舉交換的 O(n2)O(n^2)O(n2) 種情況,對答案有增量意味著交換的其中一個下標 xxx 落在某最大子段和 [l,r][l, r][l,r] 內部、或恰處于邊界 l?1,r+1l-1, r+1l?1,r+1 處。故可以枚舉下標 xxx,討論另一個交換下標 yyy:若 y>xy \gt xy>x,則 xxx 左側 [1,x?1][1, x - 1][1,x?1] 取最大的后綴和,xxx 右側 [x+1,n][x + 1, n][x+1,n] 取最大的 ay+∑i=x+1paia_y + \sum\limits_{i=x + 1}^{p} a_iay?+i=x+1p?ai?,其中 p<yp \lt yp<yx<yx \lt yx<y 的情況同理。用線段樹區(qū)間合并可以維護。

參考代碼:
#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<ll, int> pii; const int maxn = 1e5 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;int a[maxn], n;template<class T> T max(const T &a, const T &b, const T &c){return max(a, max(b, c)); } struct Node{ll sum, pmx, lmx, rmx, lpmx, prmx;int p, l, r, lp, rp;friend Node operator + (const Node &a, const Node &b){Node c;c.sum = a.sum + b.sum;tie(c.pmx, c.p) = max(pii(a.pmx, a.p), pii(b.pmx, b.p));tie(c.lmx, c.l) = max(pii(a.lmx, a.l), pii(a.sum + b.lmx, b.l));tie(c.rmx, c.r) = max(pii(b.rmx, b.r), pii(b.sum + a.rmx, a.r));tie(c.lpmx, c.lp) = max(pii(a.lpmx, a.lp), pii(a.lmx + b.pmx, b.p), pii(a.sum + b.lpmx, b.lp));tie(c.prmx, c.rp) = max(pii(b.prmx, b.rp), pii(b.rmx + a.pmx, a.p), pii(b.sum + a.prmx, a.rp));return c;} } tr[maxn << 2];struct Ans{ll v; int x, y;bool operator < (const Ans &o) const{return v < o.v;} } ans;void pushUp(int rt){tr[rt] = tr[lson] + tr[rson]; }void build(int l, int r, int rt){if(l == r){tr[rt].sum = tr[rt].pmx = tr[rt].lpmx = tr[rt].prmx = a[l];tie(tr[rt].lmx, tr[rt].l) = max(pii(a[l], l), pii(0, l - 1));tie(tr[rt].rmx, tr[rt].r) = max(pii(a[r], r), pii(0, r + 1));tr[rt].p = tr[rt].lp = tr[rt].rp = l;return;}int mid = gmid;build(l, mid, lson);build(mid + 1, r, rson);pushUp(rt); }Node query(int l, int r, int rt, int L, int R){// cout << rt << " " << l << " ?? " << r << " " << tr[rt].prmx << " " << tr[rt].rp << endl;if(l >= L && r <= R) return tr[rt];int mid = gmid;if(L <= mid && R > mid) return query(l, mid, lson, L, R) + query(mid + 1, r, rson, L, R);else if(L <= mid) return query(l, mid, lson, L, R);else return query(mid + 1, r, rson, L, R); }int main(){ios::sync_with_stdio(0); cin.tie(0);cin >> n;for(int i = 1; i <= n; ++i) cin >> a[i];build(1, n, 1);Ans ans = Ans{a[1], 1, 1};for(int i = 1; i <= n; ++i){Node ln = i > 1 ? query(1, n, 1, 1, i - 1) : Node();Node rn = i < n ? query(1, n, 1, i + 1, n) : Node();if(i > 1) ans = max(ans, Ans{ln.rmx + a[i], i, ln.r});if(i > 1) ans = max(ans, Ans{ln.prmx + rn.lmx, ln.rp, i});if(i < n) ans = max(ans, Ans{ln.rmx + rn.lpmx, i, rn.lp});// if(i == 4) cout << ln.prmx << " ?? " << ln.rp << endl;// cout << i << " " << ans.v << " " << ans.x << " " << ans.y << endl;}if(ans.x == ans.y) ans.x = 1, ans.y = n;cout << ans.v << endl;cout << ans.x << " " << ans.y << endl;return 0; }

我寫的另一種比較煩的做法,可以用來練習。枚舉 O(n2)O(n^2)O(n2) 個子段和,考慮最大化答案的情況,即內部找一個最小值與外部的最大值交換。考慮與子段內與左邊交換的情況,另一種情況將序列反轉后同理。枚舉 rrr,求 max?l=1r{∑i=lrai+max?i=1l?1ai?min?i=lr}\max\limits_{l = 1}^{r}\{\sum\limits_{i = l}^{r} a_i + \max\limits_{i = 1}^{l - 1} a_i - \min\limits_{i = l}^{r}\}l=1maxr?{i=lr?ai?+i=1maxl?1?ai??i=lminr?},迭代 rrr,用線段樹維護該值:r?1r-1r?1rrr 時,對于 ∑i=lrai\sum\limits_{i = l}^{r} a_ii=lr?ai? 這一項,只需要對 [1,r][1, r][1,r] 加上 ara_rar?;最大值項對應一次單點加;最小值項用單調棧維護,每次修改為區(qū)間加法。

#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;typedef pair<ll, int> pli; const ll oo = 1ll << 60; struct Node{ll val; int x, y;bool operator < (const Node &o) const{return val < o.val;} } ans1, ans2; ll a[maxn], b[maxn], sum[maxn]; pli mx[maxn]; pli stk[maxn]; int top; int n;struct SegTree{pli mx[maxn << 2], mn[maxn << 2]; ll add[maxn << 2];void pushUp(int rt){mx[rt] = max(mx[lson], mx[rson]);mn[rt] = min(mn[lson], mn[rson]);}void build(int l, int r, int rt){add[rt] = 0;if(l == r){mx[rt] = mn[rt] = {0, l};return;}int mid = gmid;build(l, mid, lson);build(mid + 1, r, rson);pushUp(rt);}void pushDown(int rt){if(add[rt]){add[lson] += add[rt], add[rson] += add[rt];mx[lson].first += add[rt], mx[rson].first += add[rt];mn[lson].first += add[rt], mn[rson].first += add[rt];add[rt] = 0;}}void update(int l, int r, int rt, int L, int R, ll val){if(l >= L && r <= R){add[rt] += val;mx[rt].first += val;mn[rt].first += val;return;}int mid = gmid; pushDown(rt);if(L <= mid) update(l, mid, lson, L, R, val);if(R > mid) update(mid + 1, r, rson, L, R, val);pushUp(rt);}pli queryMx(int l, int r, int rt, int L, int R){if(l >= L && r <= R) return mx[rt];int mid = gmid; pli ret = {-oo, 0}; pushDown(rt);if(L <= mid) ret = max(ret, queryMx(l, mid, lson, L, R));if(R > mid) ret = max(ret, queryMx(mid + 1, r, rson, L, R));return ret;}pli queryMn(int l, int r, int rt, int L, int R){if(l >= L && r <= R) return mn[rt];int mid = gmid; pli ret = {oo, 0}; pushDown(rt);if(L <= mid) ret = min(ret, queryMn(l, mid, lson, L, R));if(R > mid) ret = min(ret, queryMn(mid + 1, r, rson, L, R));return ret;} } tr_a, tr_sum, tr;void solve(Node &ans){sum[0] = 0, mx[0] = {-oo, 0};for(int i = 1; i <= n; ++i){sum[i] = sum[i - 1] + a[i];mx[i] = max(mx[i - 1], pli{a[i], i});}stk[top = 0] = {-oo, 0};tr_a.build(1, n, 1);tr_sum.build(1, n, 1);tr.build(1, n, 1);for(int i = 1; i <= n; ++i){tr_a.update(1, n, 1, i, i, a[i]);tr_sum.update(1, n, 1, 1, i, a[i]);tr.update(1, n, 1, 1, i, a[i]);tr.update(1, n, 1, i, i, mx[i - 1].first - a[i]);while(a[i] <= stk[top].first){pli er = stk[top--], el = stk[top];tr.update(1, n, 1, el.second + 1, er.second, er.first - a[i]);}stk[++top] = {a[i], i};pli e = tr_sum.queryMx(1, n, 1, 1, i);ll s = sum[i]; int l = e.second;Node tmp = Node{s, l, i};if(ans < tmp) ans = tmp;if(i == 1) continue;e = tr.queryMx(1, n, 1, 2, i);s = e.first, l = e.second;int pl = mx[l - 1].second, pr = tr_a.queryMn(1, n, 1, l, i).second;tmp = Node{s, pl, pr};if(ans < tmp) ans = tmp;} }int main(){ios::sync_with_stdio(0); cin.tie(0);cin >> n;for(int i = 1; i <= n; ++i) cin >> a[i];ans1.val = ans2.val = -oo;solve(ans1);reverse(a + 1, a + 1 + n);solve(ans2);ans2.x = n - ans2.x + 1;ans2.y = n - ans2.y + 1;if(ans1 < ans2) ans1 = ans2;if(ans1.x == ans1.y) ans1.x = 1, ans1.y = n;cout << ans1.val << endl;cout << ans1.x << " " << ans1.y << endl;return 0; }

G - Moore’s Law

簡要題意:

給定 nnn,構造一個數 xxx 滿足 xxx 十進制表示僅包含 111222,且 xxx2n2^n2n 的倍數。

解題思路:

遞推構造,ans1=2ans_1 = 2ans1?=2,對于 i>1i \gt 1i>1,討論 ansi?1%2ians_{i - 1} \%~ 2^iansi?1?%?2i,若余數為 2i?12^{i - 1}2i?1,則加上 10i?110^{i - 1}10i?1 使得余數為 000;若余數為 000,可不操作,或加上 2×10i?12×10^{i - 1}2×10i?1

參考代碼:
ans = [0 for i in range(43)] ans[1] = '2' for i in range(2, 43):if int(ans[i - 1]) % 2**i == 0:ans[i] = '2' + ans[i - 1]else:ans[i] = '1' + ans[i - 1] n = int(input()) print(ans[n])

I - Number builder

簡要題意:

簽到題。

解題思路:

分類討論。

參考代碼:
#include<bits/stdc++.h> using namespace std; #define pb emplace_back #define sz(a) ((int)a.size()) #define lson (rt << 1) #define rson (rt << 1 | 1) #define gmid (l + r >> 1) typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e2 + 5; const int mod = 1e9 + 7; const int inf = 0x3f3f3f3f;int main(){ios::sync_with_stdio(0); cin.tie(0);int n; cin >> n;int s = n % 3 == 1 ? 1 : 2;do{cout << s;n -= s, s = 3 - s;}while(n > 0);cout << endl;return 0; }

總結

以上是生活随笔為你收集整理的2016-2017 7th BSUIR Open Programming Contest. Final 补题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品一区二区视频 | 999xxxx| 国产调教视频在线观看 | 在线免费观看黄色小视频 | 青青操在线观看 | 一级做a爰片久久毛片潮喷 天天透天天干 | 九色综合网| 婷婷国产 | 日本高清无吗 | 国产国拍精品亚洲 | 欧美三级国产 | 日韩精品久久久久久久电影99爱 | 最新国产一区 | 91久久精品一区二区三区 | 欧美夜夜| 婷婷超碰| 欧美xxxxxhd| 天堂8中文 | 深夜福利一区 | 亚洲欧美国产视频 | 老司机午夜免费精品视频 | 超碰成人网 | 九九视频在线观看 | 97精品人妻一区二区三区 | 美女擦边视频 | 视频在线观看网站免费 | 看黄色的网址 | 欧美激情一区在线 | 午夜视频免费看 | 日本美女毛茸茸 | 国产又粗又长又黄视频 | 粉嫩av懂色av蜜臀av分享 | 欧美性猛交xxxx偷拍洗澡 | 色偷偷免费费视频在线 | 免费黄网站在线看 | 美日韩一级| 亚洲熟妇毛茸茸 | www国产亚洲精品久久网站 | 成人短视频在线免费观看 | 中文在线日韩 | 精品婷婷色一区二区三区蜜桃 | 国产性一乱一性一伧一色 | 麻豆成人免费 | 国产精品久久久久久一区二区三区 | 国内精品少妇 | 国产原创在线视频 | 啦啦啦免费高清视频在线观看 | √资源天堂中文在线 | 国产视频分类 | 涩涩资源网 | 国产色片在线观看 | 字幕网av | 中文字幕一区二区人妻电影丶 | 91国内揄拍国内精品对白 | 1000部啪啪未满十八勿入超污 | 欧洲成人在线观看 | 亚洲国产中文在线 | 下面一进一出好爽视频 | 天堂色av| 婷婷色中文字幕 | 九九精品在线视频 | 国产精品久久久久毛片大屁完整版 | 视频一区二区在线观看 | 国产福利91精品一区二区三区 | 国产高清一区二区三区四区 | 午夜美女视频 | 亚洲精品久久久久 | 90岁肥老奶奶毛毛外套 | 亚洲精品一区久久久久久 | 国产黄色片免费在线观看 | 日本a在线观看 | 日韩经典一区二区三区 | 国产在线一区二区三区四区 | 97操碰| 亚洲熟妇无码乱子av电影 | 亚州av综合色区无码一区 | 精品人妻伦一二三区免费 | 久草资源站 | 91理论片| 91精品亚洲 | 久久无码人妻一区二区三区 | 小sao货水好多真紧h无码视频 | 都市激情国产精品 | 国产精品8888 | 精品国产91 | 亚洲欧美综合另类自拍 | 国产一区黄色 | 色交视频 | 午夜视频a| 国产丝袜在线 | 亚洲色成人一区二区三区小说 | 在线视频久久 | 少妇闺蜜换浪荡h肉辣文 | 在线一区二区三区四区 | 国产资源精品 | 日韩一区在线免费观看 | 在线观看成年人网站 | 69精品人人 | 欧美有码在线观看 |