Codeforces Round #429(Div 1)
来源:互联网 发布:如何做淘宝优惠券推广 编辑:程序博客网 时间:2024/06/05 17:00
Codeforces Round #429(Div 1)
A. Leha and Function
大家都一眼了结论,只有我个sx真的去证明了…
猜想:逆序和大于等于乱序和大于等于顺序和。我们只需要证明将
也就是证明:
也就是证:
由于
#include <bits/stdc++.h>using namespace std;const int MAXN = 200005;int A[MAXN], B[MAXN], Ap[MAXN], n;priority_queue<pair<int, int> > pr;priority_queue<pair<int, int>, vector<pair<int,int> >, greater<pair<int, int> > > pr2;int main(){ scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &A[i]), pr2.push(make_pair(A[i], i)); for (int i = 1; i <= n; i++) scanf("%d", &B[i]), pr.push(make_pair(B[i], i)); for (int i = 1; i <= n; i++) { pair<int, int> a = pr2.top(), b = pr.top(); pr.pop(), pr2.pop(); Ap[b.second] = a.first; } for (int i = 1; i <= n; i++) printf("%d ", Ap[i]); puts(""); return 0;}
B. Leha and another game about graph(补)
考虑增量法构造,每一次选取两个
正确性在于,如果经过一段已经经过的路径,可以删去这段路径,并将上下两部分视为两个路径,不影响结果。
然后发现任意一个生成森林和整张图是等价的。
然后就可以喜闻乐见的NOIP经典方法树上差分了。由于异或运算的性质,甚至不需要求lca。(当然你也可以选择树剖233)。
#include <bits/stdc++.h>using namespace std;const int MAXN = 300005;int fa[MAXN];inline int findf(int i){ return fa[i]?fa[i]=findf(fa[i]):i; }struct node { int to, next, id;} edge[MAXN*2];int head[MAXN], top = 0;inline void push(int i, int j, int id){ edge[++top] = (node) {j, head[i], id}, head[i] = top; }int n, m;int d[MAXN];vector<int> vec[MAXN], v[MAXN];int depth[MAXN], pre[MAXN];int tag[MAXN], del[MAXN], cnt = 0;void dfs_calc(int nd, int f){ for (int i = head[nd]; i; i = edge[i].next) { int to = edge[i].to; if (to == f) continue; pre[to] = edge[i].id, dfs_calc(to, nd), tag[nd] ^= tag[to]; } if (tag[nd] == 1) del[pre[nd]] = 1;}int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &d[i]); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); if (findf(u) != findf(v)) fa[findf(u)] = findf(v), push(u, v, i), push(v, u, i); } for (int i = 1; i <= n; i++) { if (d[i] == 1) vec[findf(i)].push_back(i); if (d[i] == -1) v[findf(i)].push_back(i); } for (int i = 1; i <= n; i++) if (fa[i] == 0) { if ((vec[i].size()&1) && v[i].empty()) { puts("-1"); return 0; } int k = vec[i].size()/2; for (int j = 0; j < k; j++) { int a = vec[i][j], b = vec[i][j+k]; tag[a] ^= 1, tag[b] ^= 1; } if (vec[i].size()&1){ int a = vec[i][vec[i].size()-1], b = v[i][0]; tag[a] ^= 1, tag[b] ^= 1; } dfs_calc(i, 0); } for (int i = 1; i <= n; i++) if (del[i] == 1) cnt++; printf("%d\n", cnt); for (int i = 1; i <= n; i++) if (del[i] == 1) printf("%d ", i); puts(""); return 0;}
D. Destiny(补)
首先用莫队+set+线段树/树状数组很容易得到
#include <bits/stdc++.h>using namespace std;const int MAXN = 300005, N = 1<<19;int n, q;int a[MAXN];int T[MAXN], ans[MAXN];int bk;struct query { int x, y, k, id; friend bool operator < (const query &a, const query &b) { return a.x/bk == b.x/bk ? a.y < b.y : a.x < b.x; }} qy[MAXN];multiset<int> hp[MAXN];int zkw[N+N+1];inline void modify(int pos, int dt){ if (pos == 0) return; // cerr << "M" << pos << " " << dt << endl; pos += N-1; zkw[pos] = dt; for (pos >>= 1; pos; pos >>= 1) zkw[pos] = min(zkw[pos<<1], zkw[pos<<1|1]);}inline int get_ans(int L, int R){ int ans = INT_MAX; // cerr << L << " " << R << endl; for (L += N-1, R += N-1; L <= R; L >>= 1, R >>= 1) { if (L&1) ans = min(ans, zkw[L++]); if (!(R&1)) ans = min(ans, zkw[R--]); } // cerr << "Q" << L << " " << R << " " << ans << endl; return ans == INT_MAX ? -1 : ans;}inline void pop(int dt){ if (T[dt]) { hp[T[dt]].erase(dt); if (!hp[T[dt]].empty()) modify(T[dt], *hp[T[dt]].begin()); else modify(T[dt], INT_MAX); } hp[--T[dt]].insert(dt); modify(T[dt], *hp[T[dt]].begin());}inline void push(int dt){ if (T[dt]) { hp[T[dt]].erase(dt); if (!hp[T[dt]].empty()) modify(T[dt], *hp[T[dt]].begin()); else modify(T[dt], INT_MAX); } hp[++T[dt]].insert(dt); modify(T[dt], *hp[T[dt]].begin());}int main(){ scanf("%d%d", &n, &q); bk = int(sqrt(n)+0.5); if (!bk) bk = 1; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= N+N-1; i++) zkw[i] = INT_MAX; for (int i = 1; i <= q; i++) scanf("%d%d%d", &qy[i].x, &qy[i].y, &qy[i].k), qy[i].id = i; sort(qy+1, qy+q+1); int L = 1, R = 0; for (int i = 1; i <= q; i++) { while (L < qy[i].x) pop(a[L]), L++; while (L > qy[i].x) L--, push(a[L]); while (R < qy[i].y) R++, push(a[R]); while (R > qy[i].y) pop(a[R]), R--; int Lb = (qy[i].y-qy[i].x+1)/qy[i].k+1; ans[qy[i].id] = get_ans(Lb, n); } for (int i = 1; i <= q; i++) printf("%d\n", ans[i]); return 0;}
考虑分块。设块大小为
等号成立当且仅当
#include <bits/stdc++.h>using namespace std;const int MAXN = 300005;int n, q;int a[MAXN], bk, bk2;struct query { int x, y, k, id; friend bool operator < (const query &a, const query &b) { return a.x/bk2 == b.x/bk2 ? a.y < b.y : a.x < b.x; }} qy[MAXN];int T[MAXN];int g[MAXN], top = 0;int p[MAXN];int main(){ scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) scanf("%d", &a[i]), T[a[i]]++; bk = int(sqrt(5*n)+0.5); if (bk > n) bk = n; if (bk < 1) bk = 1; bk2 = int(sqrt(5*n)+0.5); if (bk2 > n) bk2 = n; if (bk2 < 1) bk2 = 1; for (int i = 1; i <= n; i++) if (T[i]*5 >= bk) g[++top] = i; for (int i = 1; i <= q; i++) scanf("%d%d%d", &qy[i].x, &qy[i].y, &qy[i].k), qy[i].id = i; sort(qy+1, qy+q+1); memset(T, 0, sizeof T); register int L = 1, R = 0; for (int i = 1; i <= q; i++) { while (L < qy[i].x) T[a[L++]]--; while (L > qy[i].x) T[a[--L]]++; while (R > qy[i].y) T[a[R--]]--; while (R < qy[i].y) T[a[++R]]++; int ans = INT_MAX, cnt = (qy[i].y-qy[i].x+1)/qy[i].k+1; if (qy[i].y-qy[i].x+1 <= bk) { for (register int j = qy[i].x; j <= qy[i].y; j++) if (T[a[j]] >= cnt) ans = min(ans, a[j]); } else { for (register int j = 1; j <= top; j++) if (T[g[j]] >= cnt) ans = min(ans, g[j]); } p[qy[i].id] = ans==INT_MAX?-1:ans; } for (int i = 1; i <= q; i++) printf("%d\n", p[i]); return 0;}
阅读全文
0 0
- Codeforces Round #429(Div 1)
- Codeforces Round #429 (Div. 2)
- Codeforces Round #429 (Div. 2)
- Codeforces Round #110 (Div. 1)
- Codeforces Round #138 (Div. 1)
- Codeforces Round #140 (Div. 1)
- Codeforces Round #153 (Div. 1)
- Codeforces Round #157 (Div. 1)
- Codeforces Round #160 (Div. 1)
- Codeforces Round #162 (Div. 1)
- Codeforces Round #165 (Div. 1)
- Codeforces Round #165 (Div. 1)
- Codeforces Round #167 (Div. 1)
- Codeforces Round #168 (Div. 1)
- Codeforces Round #174 (Div. 1)
- Codeforces Round #187 DIV 1
- Codeforces Round #198 (Div. 1)
- Codeforces Round #198 (Div. 1)
- MySQL 事务操作
- 背景图片始终居中的两种方式
- node.js Basic routing
- 文本处理sed
- TCP三次握手 四次挥手
- Codeforces Round #429(Div 1)
- Android--WebView开发项目使用这些就够了
- CentOS7使用lvm动态添加磁盘到逻辑卷/data (适用xfs文件系统)
- android-自定义View解决wrap_content无效的问题
- Android之Activity生命周期总结(一)
- FreeRTOS简介与源码下载
- css隐藏和显示
- webpack 构建Vue项目
- 华为机试-提取不重复的整数