Codeforces Round #411(Div. 2)——ABCDEF
30min水掉前面4T,30min尝试读懂EF题,60min划水
顺便D忘记取膜丢50分,距比赛结束10s时hack失败丢50分...
从2620掉分到2520,从rank227掉到rank354...血的教训
真吉尔丢人,题目戳这里
A. [L,R]中出现次数最多的因子个数
显然L != R 答案就是2,否则就是 R
B.仅用'a' 'b' 'c'造字符串,保证不能出现长度为3的回文子串,并尽量少用'c'
脑补一下发现直接aabbaabbaabb...这样子构造就可以满足了
C.n个地点标号1-n,从 i 到 j 的花费为 (i + j) % (n + 1)
出发地点和结束地点自己定,遍历全部n个地点的最小花费
我们如果直接 1 -> n , 2 -> (n - 1) ...这样子走每次花费就都是0
然后我们想办法连接他们,发现可以 1 -> n -> 2 -> (n - 1) -> 3 -> (n - 2) ...
所以answer = (n - 1) / 2
D.给个只包含'a''b'的字符串,遇'ab'就要换成'bba',求问到不能变换为止的最少变换次数
我们可以发现
1.变换后'a'的个数不变,b的个数1个变2个
2.最后字符串形式一定为bb...bbaa...aa
于是我们从后往前记录'b'的个数cnt,若遇到一个'a',那么它后面的'b'的个数
即这个'a'引起的需要变换的次数,即ans += cnt, 且经过cnt次变换后,'b'的个数变成了cnt * 2个
然后一直往前边扫边算就好了
#include <bits/stdc++.h> using namespace std; char s[]; int main() {
int n, mod_ = 1e9 + ;
long long m = , ans = ;
scanf("%s", s);
for(int i = strlen(s) - ;i >= ;i --) {
if(s[i] == 'b') m ++;
else ans += m, ans %= mod_, m = m * % mod_;
}
cout << ans;
return ;
}
E.给一棵n个点的树,树上每个节点都有一个集合,每个集合中包含若干种cream
由m种cream构成的无向图G,若cream_u与cream_v之间有边
当且仅当树上存在一点,cream_u与cream_v同时存在该点的集合中
然后对图G的节点进行染色,使得任意一边连接的两点不同色
输出最少颜色数和任一方案
令一重要条件:任一cream存在的树上节点都构成一个联通子图,即
Vertices which have the i-th (1 ≤ i ≤ m) type of ice cream form a connected subgraph.
做题时感觉这棵树存在意义不大...是因为没有明白这个条件的用法
我们来直观的考虑一下这个条件,如果cream_i 存在于节点u的父亲节点中
却没有存在于u中,那么显然cream_i 不会再存在于以u为根节点的这个子树中了
所以我们就可以做了,从根节点开始 dfs,对于当前节点的集合中的所有cream
如果cream_i 在父亲节点中存在,那么它的颜色号就被标记为不可用
若不存在,那么就从 1 开始找可用的颜色号给它用就好了
一个小坑:可能有没有在树上出现过的cream,直接给它染成颜色1就好了
#include <cstdio>
#include <vector>
using namespace std; const int maxn = ; int n, m, k, d[maxn], g[maxn];
vector <int> e[maxn], f[maxn]; void dfs(int u, int fa) {
int i, j = ;
for(i = ;i < e[u].size();i ++)
if(d[e[u][i]])
g[d[e[u][i]]] = ;
for(i = ;i < e[u].size();i ++)
if(!d[e[u][i]]) {
while(g[j]) j ++;
d[e[u][i]] = j;
k = max(k, j);
j ++;
}
for(i = ;i < e[u].size();i ++)
g[d[e[u][i]]] = ;
for(i = ;i < f[u].size();i ++)
if(f[u][i] != fa)
dfs(f[u][i], u);
} int main() {
int u, v;
scanf("%d %d", &n, &m);
for(int i = ;i <= n;i ++) {
scanf("%d", &k);
for(int j = ;j <= k;j ++)
scanf("%d", &u), e[i].push_back(u);
}
for(int i = ;i < n;i ++) {
scanf("%d %d", &u, &v);
f[u].push_back(v);
f[v].push_back(u);
}
k = , dfs(, -);
printf("%d\n", k);
for(int i = ;i <= m;i ++)
if(!d[i])
d[i] = ;
for(int i = ;i <= m;i ++)
printf("%d ", d[i]);
return ;
}
F.给你一个森林,然后给你 q 组询问,每组询问包含 u 和 v
若在节点 u 所在的树和节点 v 所在的树之间随机加一条边的话,求新树的直径的期望值
(q神给的)解题思路:
如果只有一组,那么经过一开始的O(n)预处理后,我们可以O(min(siz[u], siz[v]))的时间求出来的
(如果能想到这个复杂度的话,可以跳过下面2段)
首先说明我们的预处理,包括每棵树的siz,直径,每个节点所在的树的编号
以及 len[i] 表示点 i 距离它所在的树中最远点的距离,显然有len[i] < siz[i] ,即肯定小于所在树的siz
然后预处理出关于len的权值前缀和之类,预处理基本结束
然后考虑只有一组询问的话,两棵树加一条边成一棵树
新的直径要么是原来一棵树的直径,要么是连接的两个点的 len 之和 + 1
即 old_d = max(du, dv), new_d = max(len[u] + len[v] + 1, old_d,)
我们只要处理出有多少组 len[u] + len[v] + 1> old_d,这些组都算前者,其余都算后者就好了
这时候就可以用到我们预处理出的权值前缀和了
对于确定的len[u],可以O(1)求出另一棵树中len[v] > old_d - len[u] - 1的 len[v] 之和
所以就可以做到O(min(siz[u], siz[v]))了
那么一组解决了,q组呢,用我们的比格思茅大法来证明复杂度!
首先令 siz_k = sqrt(n)
如果 u 和 v 所在的树有一棵树的siz < siz_k,即存在为思茅的话
那么这次询问的时间就是不超过O(sqrt(n))的
那么如果两颗树的 siz 均大于呢,即均为比格的话
因为上述算法取决于 siz 小的树的 siz
那么考虑最坏情况,两颗树 siz 相同且均大于 siz_k
那么如果查询所有不同的pair效率是多少呢, (n / siz) ^ 2 * siz
即n ^ 2 / siz,由于 siz > sqrt(n),所以 最坏O(n * sqrt(n))
当然为了避免同一pair重复查询可以用map来记忆化一下
综上,考虑map因素,时间O(n * sqrt(n) * logn)
然而实际表现还是相当不错的!
#include <bits/stdc++.h> #define pb push_back
#define rep(i, j, k) for(int i = j;i < (k + 1);i ++) using namespace std; typedef long long ll; const int maxn = ; bool vis[maxn]; int n, m, q, ks, st, dis; int cnt, cot, zx[maxn], siz[maxn], tmp[maxn], len[maxn], dlen[maxn]; vector <int> e[maxn];
vector <ll> f2[maxn], f1[maxn], f3[maxn]; struct node {
int x, y; bool operator < (const node &a) const {
if(x == a.x) return y < a.y;
return x < a.x;
}
}; map <node, double> p; void dfs1(int x, int f, int d) {
int y;
vis[x] = , cot ++;
if(d > dis) dis = d, st = x;
rep(i, , e[x].size() - ) {
y = e[x][i];
if(y == f) continue;
zx[y] = zx[x];
dfs1(y, x, d + );
}
} void dfs2(int x, int f, int d) {
int y;
len[x] = max(len[x], d);
if(d > dis) dis = d, st = x;
rep(i, , e[x].size() - ) {
y = e[x][i];
if(y != f) dfs2(y, x, d + );
}
} void dfs3(int x, int f) {
int y;
tmp[len[x]] ++;
rep(i, , e[x].size() - ) {
y = e[x][i];
if(y != f) dfs3(y, x);
}
} int main() {
ll s;
node temp;
int u, v, w, t;
double ans1, ans2;
ios::sync_with_stdio(false); cin >> n >> m >> q;
ks = (int)sqrt(n + 0.5); rep(i, , m) {
cin >> u >> v;
e[u].pb(v), e[v].pb(u);
} rep(i, , n) if(!vis[i]) {
cot = ;
zx[i] = ++cnt;
dis = -, dfs1(i, i, ), siz[cnt] = cot;
dis = -, dfs2(st, st, ), dlen[cnt] = dis;
dis = -, dfs2(st, st, );
dfs3(i, i);
rep(j, , dlen[cnt]) f3[cnt].pb(tmp[j]);s = ;
rep(j, , dlen[cnt]) f1[cnt].pb(s += tmp[j]);s = ;
rep(j, , dlen[cnt]) f2[cnt].pb(s += 1ll * j * tmp[j]);
rep(j, , dlen[cnt]) tmp[j] = ;
} rep(i, , q) {
cin >> u >> v;
if(zx[u] == zx[v]) puts("-1");
else {
ans1 = ans2 = ;
u = zx[u], v = zx[v];
if(siz[u] > siz[v]) swap(u, v);
if(siz[u] <= ks) {
w = max(dlen[u], dlen[v]);
rep(j, , dlen[u])
{
t = w - j - ;
if(t < ) ans1 += f3[u][j] * (f2[v][dlen[v]] + f1[v][dlen[v]] * ( + j));
else if(t > dlen[v]) ans1 += f3[u][j] * (f1[v][dlen[v]] * w);
else ans1 += f3[u][j] * (f2[v][dlen[v]] - f2[v][t] + (f1[v][dlen[v]] - f1[v][t]) * ( + j) + f1[v][t] * w);
}
ans2 = 1.0 * siz[u] * siz[v];
printf("%.10f\n", ans1 / ans2);
}
else {
if(p[(node){u, v}]) printf("%.10f\n", p[(node){u, v}]);
else
{
w = max(dlen[u], dlen[v]);
rep(j, , dlen[u])
{
t = w - j - ;
if(t < ) ans1 += f3[u][j] * (f2[v][dlen[v]] + f1[v][dlen[v]] * ( + j));
else if(t > dlen[v]) ans1 += f3[u][j] * (f1[v][dlen[v]] * w);
else ans1 += f3[u][j] * (f2[v][dlen[v]] - f2[v][t] + (f1[v][dlen[v]] - f1[v][t]) * ( + j) + f1[v][t] * w);
}
ans2 = 1.0 * siz[u] * siz[v];
printf("%.10f\n", ans1 / ans2);
p[(node){u, v}] = ans1 / ans2;
}
}
}
}
}
代码有点丑,半夜撸了2h的代码非常狗
下午又调了1h才调出来,谨慎参考,希望能有所帮助
Codeforces Round #411(Div. 2)——ABCDEF的更多相关文章
- Codeforces Round #531 (Div. 3) ABCDEF题解
Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...
- Codeforces Round #527 (Div. 3) ABCDEF题解
Codeforces Round #527 (Div. 3) 题解 题目总链接:https://codeforces.com/contest/1092 A. Uniform String 题意: 输入 ...
- Codeforces Round #411 (Div. 2)(A,B,C,D 四水题)
A. Fake NP time limit per test:1 second memory limit per test:256 megabytes input:standard input out ...
- Codeforces Round #Pi (Div. 2) ABCDEF已更新
A. Lineland Mail time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces Round #411 (Div. 1) D. Expected diameter of a tree
题目大意:给出一个森林,每次询问给出u,v,问从u所在连通块中随机选出一个点与v所在连通块中随机选出一个点相连,连出的树的直径期望(不是树输出-1).(n,q<=10^5) 解法:预处理出各连通 ...
- Codeforces Round #411 (Div. 2)
来自FallDream的博客,未经允许,请勿转载,谢谢. 由于人傻又菜 所以这次又滚去div2了 一堆结论题真的可怕 看见E题不是很有思路 然后就去大力搞F题 T了最后一个点 真的绝望 但 ...
- Codeforces Round #411 div 2 D. Minimum number of steps
D. Minimum number of steps time limit per test 1 second memory limit per test 256 megabytes input st ...
- Codeforces Round #411 (Div. 2) 【ABCDE】
A. Fake NP 题意:给你l,r,让你输出[l,r]里面除1以外的,出现因子数量最多的那个数. 题解:如果l==r输出l,否则都输出2 #include<bits/stdc++.h> ...
- Codeforces Round #411 (Div. 2) C. Find Amir
C. Find Amir time limit per test 1 second memory limit per test 256 megabytes A few years ago ...
随机推荐
- 获取Access数据里所有表的名称和表的字段
-------------//获取Access数据库表名 public void GetTableName() { string connSt ...
- bzoj1297 [SCOI2009]迷路——拆点+矩阵快速幂
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1297 一看感觉是矩阵快速幂之类的,但边权不好处理啊: 普通的矩阵快速幂只能处理边权为1的,所 ...
- E20171014-hm
Sibling n. 兄弟,姐妹; [生] 同科,同属; [人] 氏族成员;
- 第一个只出现一次的字符--java实现
/** * 主要思想是通过数组来保存每个字符的出现次数,数组访问O(1),所以总时间复杂度可以保持O(n),通过两次遍历可以解决问题 * @param ch * @return */ public s ...
- Eclipse 添加 YAML插件
官网:https://github.com/oyse/yedit 离线版本:(链接: https://pan.baidu.com/s/1PJzkS1tI-VigZvfbYXUh9A 密码: gfep) ...
- jmeter中beanshell断言的使用
简单使用beanshell的内容,进行测试内容的判断 这里通过断言内容,修改if的条件,达到发送警报邮件的功能 beanshell 代码如下: SampleResult 等效于 prev lo ...
- 51nod 1340 差分约束
思路: 带未知量的Floyd 很强 http://yousiki.net/index.php/archives/87/ //By SiriusRen #include <bits/stdc++. ...
- ACM_开挂的小G
开挂的小G Time Limit: 2000/1000ms (Java/Others) Problem Description: 小G寒假在家没网络,闲着没事干又看不下书,就玩起了单机游戏ACM_Ga ...
- Web程序安全机制
ASP.NET提供了一个多层的安全模型,这个模型能够非常容易的保护Web应用程序. 安全策略没有必要非常复杂,但是需要应用安全策略的地方却是非常广泛的.程序员需要保证自己的应用程序不能被骗取,而把私有 ...
- drupal 8——图片组(list)在前台的显示顺序在登录状态和非登录状态不同
问题描述:该页面是通过view来输出的,然而,登录状态下其页面中的图片组输出顺序是乱序的,而非登录状态下则根据id值升序输出. 原因:在原view配置页面中,没有配置默认的排序字段 解决方案:在vie ...