多校第四场补题
来源:互联网 发布:数据库视频教学 编辑:程序博客网 时间:2024/05/21 06:01
1004
题意
题目一通描述,弄得我完全懵逼。幸好讨论区,有题目意思。
题目意思为:定义f(l,r) 为区间 [l,r] 的不同元素个数/区间长度。求最小的 f(l,r) 定义域:
。题目意思,翻译转一下就是这么简单。
我很菜,想不出来
看了克拉丽丝的题解还是想不出来
看别人blog看懂了
思路就是,官方题解给出的,二分+线段树;我们二分答案,mid。需要判断mid是否满足,假设我们定义
为区间 [l,r] 的不同元素个数。那么就需要mid满足:
,按照题解进行变形式子可以得到:
,我们可以对r进行从左到右的枚举。在每一次枚举中r就是一个常数。我们可以用线段树维护区间最小值,维护
,每次r+1,需要更新r,r这个区间,区间加mid×r。还有需要给r区间到之前出现a[r]位置的右边这个区间的size都会加1。所以两次更新,每次我们需要查询区间 [1,r] 的区间最小值。先写一个区间维护最小值的插线问线的线段树。进行二分 。over;二分的时候,如果满足条件说明mid还不是最小的所以把上限
,否则下限
;
克拉丽丝快穿JK啊
克拉丽丝的代码好挤啊,没有阅读欲望
自己用毒瘤线段树写一开始wa了,以为是减法运算的锅,
然后,黑康说,你tmp是不是应该是double
好的,我是傻逼
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const int N = 2e5 + 10;double EPS = 1e-11;int n, pos[N], arr[N], pre[N];struct ZKWsegTree{ double tree[N]; int M, n; void build(int n, double Mid){ this->n = n; M = 1; while (M < n) M <<= 1; if (M!=1) M--; for (int t = 1 ; t <= n; t++) tree[t+M] = 1.0*t*Mid; for (int t = n+1; t <= M+1; t++) tree[t+M] = M * 2; for (int t = M; t >= 1; t--) tree[t] = min(tree[t<<1], tree[t<<1^1]); for (int t = 2*M+1; t >= 1; t--) tree[t] = tree[t] - tree[t>>1]; } void update(int l, int r, double val){ double tmp; for (l+=M-1, r+=M+1; l^r^1; l>>=1, r>>=1){ if (~l&1) tree[l^1] += val; if ( r&1) tree[r^1] += val; if (l > 1) tmp = min(tree[l], tree[l^1]), tree[l]-=tmp, tree[l^1]-=tmp, tree[l>>1]+=tmp; if (r > 1) tmp = min(tree[r], tree[r^1]), tree[r]-=tmp, tree[r^1]-=tmp, tree[r>>1]+=tmp; } for (; l > 1; l >>= 1){ tmp = min(tree[l], tree[l^1]), tree[l]-=tmp, tree[l^1]-=tmp, tree[l>>1]+=tmp; } tree[1] += tree[0], tree[0] = 0; } double query(int l, int r){ double lAns = 0, rAns = 0; l += M, r += M; if (l != r){ for (; l^r^1; l>>=1, r>>=1){ lAns += tree[l], rAns += tree[r]; if (~l&1) lAns = min(lAns, tree[l^1]); if ( r&1) rAns = min(rAns, tree[r^1]); } } double ans = min(lAns + tree[l], rAns + tree[r]); for (;l > 1;) ans += tree[l>>=1]; return ans; }} T;bool check(double Mid){ T.build(n, Mid); for (int r = 1; r <= n; r++){ T.update(pre[r] + 1, r, 1.0); double ans = T.query(1, r); if (ans <= Mid * (r + 1)) return true; } return false;}int main(){ //freopen("in.txt", "r", stdin); int _; scanf("%d", &_); for (;_--;){ scanf("%d", &n); memset(pos, 0, sizeof(pos)); for (int i = 1; i <= n; i++){ scanf("%d", &arr[i]); pre[i] = pos[arr[i]]; pos[arr[i]] = i; } double L = 0, R = 1; for (;R - L > EPS;){ double Mid = (L + R) / 2.0; if (check(Mid)) R = Mid; else L = Mid; } printf("%.10lf\n", R); } return 0;}
1005
码个题解,过两天补
1007
克拉丽丝题解
首先如果一个点的度数为1,那么它的匹配方案是固定的,继而我们可以去掉这一对点。通过拓扑我们可以不断去掉所有度数为1的点。
那么剩下的图中左右各有m个点,每个点度数都不小于2,且左边每个点度数都是2,而右侧总度数是2m,因此右侧只能是每个点度数都是2。这说明这个图每个连通块是个环,在环上间隔着取即可,一共两种方案。
时间复杂度O(n)。
这题的wa点在于,有很多个环,环与环之间解的合并,这一个是看了克拉丽丝的代码才发现的
其实,是对于每个环有2种方案,环和环之间
common*(X1+Y1)(X2+Y2)….*(XP+YP)=ans
一开始看不懂,以为组合数学烂,后来看这里发现,乘法分配律合并后就是这样
自己的实现方式很蠢,其实是个偶环,一遍dfs统计奇偶就好了,不过看函数名应该就能猜出是啥意思了吧
还有const的时候N和M要分开估计,很容易炸,而且炸了还不返回RTE,返回的TLE
#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>using namespace std;typedef long long LL;const LL MOD = 998244353;const int N = 8e5 + 10;const int M = 2e6 + 10;struct graph{ struct Edge{ int from, to, Next, Last; LL cost; Edge(){Next = -1; Last = -1;} Edge(int f, int t, LL c, int n, int l):from(f), to(t), cost(c), Next(n), Last(l){} } edges[M]; bool vis[N]; int n, in[N], E, head[N]; inline void init(int n){ del_time = 0; this->n = n, E = -1; memset(in, 0, sizeof(in)); memset(vis, 0, sizeof(vis)); memset(head, -1, sizeof(head)); } inline void addEdge(int f, int t, LL c){ //printf("addEdge(%d, %d, %lld)\n", f, t, c); edges[++E] = Edge(f, t, c, head[f], 0); edges[head[f]].Last = E; head[f] = E; in[t]++; //printf("in[%d] = %d\n", t, in[t]); } inline void delEdge(int t){ del_time++; //printf("delEdge(%d)\n", t); Edge &e = edges[t]; if (head[e.from] == t) head[e.from] = e.Next; else{ edges[e.Last].Next = e.Next; if (e.Next != -1) edges[e.Next].Last = e.Last; } in[e.to]--; //printf("after delete, in[%d] = %d\n", e.to, in[e.to]); } LL del_top(){//从度为1的点开始删 LL ans = 1; int v; vector <int> po; for (int i = n/2+1; i <=n; i++) { //printf("in[%d] = %d\n", i, in[i]); if (in[i] == 1) po.push_back(i); } bool flag = 0; for (int i = 0; i < po.size(); i++){ int v = po[i]; for (int cnt = 1; in[v] == 1; cnt++){ vis[v] = 1; //printf("v = %d\n", v); int h = head[v]; Edge &e = edges[h]; if (cnt&1) ans = (1LL * ans * e.cost) % MOD; delEdge(h); delEdge(h^1); v = e.to; } } //printf("base = %lld\n", ans); return ans % MOD; } LL get_ans(int t){ //printf("edge_num = %d\n", t); Edge e = edges[t]; LL ans = 1; int start = e.from, last; //printf("start = %d\n", start); for (int cnt = 1; e.to != start; cnt++){ //printf("to = %d, cost = %lld\n", e.to, e.cost); if (cnt&1) ans = (1LL * ans * e.cost) % MOD; last = e.from; vis[last] = 1; vis[e.to] = 1; e = edges[head[e.to]]; if (e.to == last) e = edges[e.Next]; } return ans; } LL solve(){ LL ans = del_top(); //printf("base = %lld\n", base); for (int i = 1; i <= n; i++) if (!vis[i]){ LL x = get_ans(head[i]); LL y = get_ans(edges[head[i]].Next); //printf("%lld + %lld\n", x, y); ans = (1LL * ans * ((x+y)%MOD)) % MOD; //printf("ans = %lld\n", ans); } return ans % MOD; }} g;int main(){ //freopen("in.txt", "r", stdin); //freopen("out.txt","w", stdout); int _, v, n; scanf("%d", &_); for (LL c; _--;){ scanf("%d", &n); //printf("n = %d\n", n); g.init(n * 2); for (int i = 1; i <= n; i++){ for (int j = 0; j < 2; j++){ scanf("%d%lld", &v, &c); v += n; g.addEdge(i, v, c); g.addEdge(v, i, c); } } LL ans = g.solve(); printf("%lld\n", ans); } return 0;}
- 多校第四场补题
- 多校第四场
- 多校第四场
- 2013 多校第四场
- 多校联赛第四场
- 2012多校第四场总结
- 2013多校联合训练第四场
- hdu 4639 Hehe 多校第四场
- hdu 4638 Group 多校第四场
- 130801hdu多校第四场结题报告
- HDOJ多校联合第四场
- 2015 多校第四场 Walk Out
- hdu5319&hdu多校集训第四题
- 多校第四场一二题
- 2015多校第四场总结
- 2016多校联合第四场 HDU5768
- HDU 5774 多校联赛第四场
- 2016多校第四场 HDU5769
- css优先级
- 数组常见问题
- leetcode 括号组合题目 20 是否是有效括号 32 最大有效括号 301 去掉无效括号
- 双内网渗透代理之reGeorg+Proxifier
- apache允许https访问及ssl免费证书申请
- 多校第四场补题
- 如何在Linux下查看分区和剩余空间大小
- iOS Hacker 反注入和反反注入
- matlab函数表
- 禁止 EditText 自动获取焦点 弹出软键盘
- Networking
- WUST OJ 1498: Wavio序列
- Android BroadcastReceiver之短信拦截(黑名单)
- mybatis 中使用association返回一条数据