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 ...
 
随机推荐
- 【SQL Server】SQL触发器经验详解
			
[SQL Server]SQL触发器经验详解 | 浏览: 4314 | 更新: 2013-01-07 15:33 25 11 全文阅读分步阅读 加入杂志 步骤 1 2 3 4 5 6 7 8 ...
 - CodeForces - 556D
			
D. Case of Fugitive time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
 - bzoj1345
			
贪心 这并没有想清楚就看题解了... 看上去肯定是贪心,那么怎么贪呢?事实上,我们想一下,假设max(a[i],a[i+1])中a[i]没有合并,那么后面取max肯定是a[i+1],因为如果后面合并之 ...
 - PCB genesis 大孔扩孔(不用G84命令)实现方法
			
PCB钻孔时,当钻刀>6.3mm时,超出钻孔范围,钻孔工序是没有这么大的钻刀,当这种情况,工程CAM会都采用G84命令用小孔扩孔的方式制作, 在这里介绍一种如果不用G84命令,用程序实现将大孔生 ...
 - JavaScript学习四
			
2019-06-01 09:09:23 坚持,加油!!! 函数的学习 <html> <head> <script type="text/javascript&q ...
 - 通过Oracle透明网关连接Sybase
			
Oracle公司提出的透明网关技术可用于实现与其他多种类型的数据库的互联,实现不同类型数据之间建立连接,方便于使用者进行查询.近日,在公司的某项目的实施过程中,开发人员需要访问Sybase数据库中的某 ...
 - netty学习:UDP服务器与Spring整合(2)
			
上一篇文章中,介绍了netty实现UDP服务器的栗子. 本文将会对UDP服务器与spring boot整合起来,并使用RedisTemplate的操作类访问Redis和使用Spring DATA JP ...
 - OFDM同步算法之Minn算法
			
minn算法代码 算法原理 训练序列结构 T=[B B -B -B],其中B表示由长度为N/4的复伪随机序列PN,ifft变换得到的符号序列 (原文解释):B represent samples of ...
 - Python--10、进程知识补充
			
守护进程 基于进程启动的子进程,会和主进程一起结束.主进程结束的依据是程序的代码执行完毕. #创建守护进程p=Process(task) p.daemon = True p.start() 子进程需要 ...
 - drupal 8——图片组(list)在前台的显示顺序在登录状态和非登录状态不同
			
问题描述:该页面是通过view来输出的,然而,登录状态下其页面中的图片组输出顺序是乱序的,而非登录状态下则根据id值升序输出. 原因:在原view配置页面中,没有配置默认的排序字段 解决方案:在vie ...