来自FallDream的博客,未经允许,请勿转载,谢谢。


由于人傻又菜 所以这次又滚去div2了  一堆结论题真的可怕

看见E题不是很有思路   然后就去大力搞F题  T了最后一个点 真的绝望   但是还是上紫了

感觉每次cf都在乱打 我好菜啊都不会

A.Fake NP

给定l和r,求[l,r]中的数的因数中出现次数最多的那一个

sb题 如果l和r相同输出它 不然输出2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} int l,r; int main()
{
l=read();r=read();
if(r==l)printf("%d\n",l);
else puts("");
return ;
}

B. 3-palindrome

要求构造一个由abc组成的字符串 满足没有长度为3的回文子串的情况下c最少

sb题...发现只用ab构造出aabbaabbaabb....就能满足条件 c根本就用不到。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} int n; int main()
{
n=read();
for(int i=;i<=n/;++i)
printf("aabb");
n%=;
if(n)printf("a");
if(n>) printf("a");
if(n>) printf("b");
return ;
}

C.Find Amir

有n个点,从第i个点到第j个点的费用是(i+j) % (n+1) 求从任意点出发 到达所有点的最小费用

走法1->n->2->n-1->3->n-2...显然最优  输出(n-1)/2即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} int n; int main()
{
n=read();
printf("%d\n",(n+)/-);
return ;
}

D.Minimum number of steps

给定一个由'a'和'b'组成的串  你要不断的把ab换成bba 直到没有ab 求换多少次,答案取膜10^9+7

打表发现 前面x个a,最后接上去一个b需要的交换次数是2^x -1 并且末尾的a的个数不变 所以直接计算即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
#define mod 1000000007
#define MN 1000000
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} int s[MN+],ans=;
char st[MN+]; int main()
{
scanf("%s",st+);
for(int i=,j=;i<=MN+;++i,j=(j<<)%mod)
s[i]=j;
for(int i=,k=;st[i];++i)
if(st[i]=='a') ++k;
else (ans+=(k==?:s[k]-))%=mod;
printf("%d\n",ans);
return ;
}

E.  Ice cream coloring

有一棵树,每个节点都有一些1-m的数字,个数和不超过5*10^5

要求你给1-m每个数字一个颜色 满足任意两个相同颜色的没有出现在同一个节点

保证1-m这些数字出现的位置构成原树的一个子图 n,m<=3*10^5

因为这些数字都是连续的 所以假设一个数字在一个节点出现,却没在它的一个儿子节点出现,那么它的那个儿子所在的子树一定没有它

所以直接贪心即可 到达每一个节点的时候给这个节点上的数字中所有已经涂过的颜色打标记 然后给还没涂色的涂尽量小的颜色。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define ld long double
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
#define MN 300000
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} int n,m,head[MN+],mark[MN+],ans=,cnt=,col[MN+];
struct edge{int to,next;}e[MN*+];
vector<int> v[MN+]; inline void ins(int f,int t)
{
e[++cnt]=(edge){t,head[f]};head[f]=cnt;
e[++cnt]=(edge){f,head[t]};head[t]=cnt;
} void Solve(int x,int fa)
{
for(int i=;i<v[x].size();++i) mark[col[v[x][i]]]=x;
for(int i=,j=;i<v[x].size();++i)
{
for(;mark[j]==x;++j);
if(!col[v[x][i]]) col[v[x][i]]=j++;
}
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa) Solve(e[i].to,x);
} int main()
{
n=read();m=read();
for(int i=;i<=n;++i)
{
int x=read();ans=max(ans,x);
for(int j=;j<=x;++j) v[i].push_back(read());
}
for(int i=;i<n;++i) ins(read(),read());
Solve(,);printf("%d\n",ans);
for(int i=;i<=m;++i)
printf("%d ",col[i]?col[i]:);
return ;
}

F.Expected diameter of a tree

给定一个森林,每次询问两棵树,如果随机连接这两棵树上的一个节点,得到的新的树的直径的期望长度。n,m<=10^5

考虑先dp+换根求出所有点为端点在它所在的树上的最长链 同时求出每个树的直径 然后把每棵树上的所有节点的最长链长度排序

查询的时候直接暴力 两个指针推一推(相加必须大于两棵树直径的较大值,否则对答案的贡献就是原树上的直径) (其实二分比较科学)

这样暴力做每次的复杂度是O(n)的 但是发现不同的询问不会太多 所以加一个哈希即可。

期望复杂度大概是根号吧  然后注意在暴力的时候 选择枚举比较小的那棵树 推另一棵树的指针  我没写这个T了一个点(不然应该能混一个第6左右)

大概就是这样吧  第一百多个点T了是最气的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define ll long long
#define ld long double
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
#define MN 100000
using namespace std;
inline int read()
{
int x = ,f = ; char ch = getchar();
while(ch < '' || ch > ''){if(ch == '-') f = ;ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return f?x:-x;
} map<ll,double> mp;
vector<int> v[MN+];
int head[MN+],mx[MN+],mx2[MN+],from[MN+],F[MN+],f[MN+],cnt=,n,m,q,bel[MN+],tot=,rt[MN+];
struct edge{int to,next;}e[MN*+];
bool mark[MN+]; inline void ins(int f,int t)
{
e[++cnt]=(edge){t,head[f]};head[f]=cnt;
e[++cnt]=(edge){f,head[t]};head[t]=cnt;
} void Dp(int x,int fa)
{
mark[x]=;bel[x]=tot;
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa)
{
Dp(e[i].to,x);int val=mx[e[i].to]+;
F[x]=max(F[x],F[e[i].to]);
if(val>mx[x]) mx2[x]=mx[x],mx[x]=val,from[x]=e[i].to;
else if(val>mx2[x]) mx2[x]=val;
}
F[x]=max(F[x],mx[x]+mx2[x]);
}
inline void R(int&a,int&b,int&c,int d){if(d>=a)c=a,a=d,b=;else if(d>=c)c=d;}
void Solve(int x,int fa)
{
v[bel[x]].push_back(mx[x]);
for(int i=head[x];i;i=e[i].next)
if(e[i].to!=fa)
{
R(mx[e[i].to],from[e[i].to],mx2[e[i].to],(e[i].to==from[x]?mx2[x]:mx[x])+);
Solve(e[i].to,x);
}
} void Calc(int x,int y)
{
x=bel[x];y=bel[y];int Mx=max(F[rt[x]],F[rt[y]]);
if(v[x].size()>v[y].size()) swap(x,y);
ll ans=;ll Tot=,k=v[y][v[y].size()-]+;
for(int i=,j=v[y].size()-;i<v[x].size();++i)
{
while(j>&&v[y][j-]+v[x][i]+>=Mx) k+=v[y][--j]+;
if(v[x][i]+v[y][j]+>=Mx)
{
Tot+=v[y].size()-j;
ans+=(ld)k+1LL*(v[y].size()-j)*v[x][i];
}
}
ll sz=1LL*v[x].size()*v[y].size();
ans+=(sz-Tot)*Mx;
if(x>y) swap(x,y);
ll ha=1LL*x*(tot+)+y;
printf("%.8lf\n",mp[ha]=(double)ans/sz);
} bool check(int x,int y)
{
x=bel[x],y=bel[y];if(x>y) swap(x,y);
ll ha=1LL*x*(tot+)+y;
if(mp[ha]>) return printf("%.8lf\n",(double)mp[ha]),true;
return false;
} int main()
{
n=read();m=read();q=read();
for(int i=;i<=m;++i)
ins(read(),read());
for(int i=;i<=n;++i) if(!mark[i])
Dp(rt[++tot]=i,);
for(int i=;i<=tot;++i)
Solve(rt[i],),sort(v[i].begin(),v[i].end());
for(int i=;i<=q;++i)
{
int x=read(),y=read();
if(bel[x]==bel[y]) puts("-1");
else if(!check(x,y)) Calc(x,y);
}
return ;
}

Codeforces Round #411 (Div. 2)的更多相关文章

  1. 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 ...

  2. Codeforces Round #411 (Div. 1) D. Expected diameter of a tree

    题目大意:给出一个森林,每次询问给出u,v,问从u所在连通块中随机选出一个点与v所在连通块中随机选出一个点相连,连出的树的直径期望(不是树输出-1).(n,q<=10^5) 解法:预处理出各连通 ...

  3. 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 ...

  4. Codeforces Round #411 (Div. 2) 【ABCDE】

    A. Fake NP 题意:给你l,r,让你输出[l,r]里面除1以外的,出现因子数量最多的那个数. 题解:如果l==r输出l,否则都输出2 #include<bits/stdc++.h> ...

  5. 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 ...

  6. Codeforces Round #411 (Div. 2) A-F

    比赛时候切了A-E,fst了A Standings第一页只有三个人挂了A题,而我就是其中之一,真™开心啊蛤蛤蛤 A. Fake NP time limit per test 1 second memo ...

  7. 【DFS】【贪心】Codeforces Round #411 (Div. 1) C. Ice cream coloring

    对那个树进行dfs,在动态维护那个当前的冰激凌集合的时候,显然某种冰激凌仅会进出集合各一次(因为在树上形成连通块). 于是显然可以对当前的冰激凌集合贪心染色.暴力去维护即可.具体实现看代码.map不必 ...

  8. 【推导】Codeforces Round #411 (Div. 1) B. Minimum number of steps

    最后肯定是bbbb...aaaa...这样. 你每进行一系列替换操作,相当于把一个a移动到右侧. 会增加一些b的数量……然后你统计一下就行.式子很简单. 喵喵喵,我分段统计的,用了等比数列……感觉智障 ...

  9. 【推导】Codeforces Round #411 (Div. 1) A. Find Amir

    1 2 3 4 5 6 7 4-5-3-6-2-7-1 答案是(n-1)/2 #include<cstdio> using namespace std; int n; int main() ...

随机推荐

  1. JAVAGUI设计步骤

    ①创建容器 首先要创建一个GUI应用程序,需要创建一个用于容纳所有其它GUI组件元素的载体,Java中称为容器.典型的包括窗口(Window).框架(Frame/JFrame).对话框(Dialog/ ...

  2. 201421123042 《Java程序设计》第12周

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...

  3. 安装Loadrunner 11.0时,弹出缺少2.8 sp1组件--解决方案(win7)

    这是因为注册表缺少FullInstallVer和Version,归根到底是madc安装的的问题 以下是解决方法: 1.运行regedit,打开注册表,进入HKEY_LOCAL_MACHINE\SOFT ...

  4. Linux系统把/home重新挂载到其他硬盘或分区

    一开始没有做好规划,导致/home空间不足,再加上分区表不是GPT,导致无法扩展超过2T,因此需要重新划分一块更大的硬盘给/home. 1.把新挂载的4T硬盘进行分区和格式化 2.创建目录 sudo ...

  5. OAuth2.0学习(1-4)授权方式1-授权码模式(authorization code)

    参与者列表: (1) Third-party application:第三方应用程序,又称客户端(client),如:"云冲印".社交应用. (2)HTTP service:HTT ...

  6. 九、Python+Selenium模拟用QQ登陆腾讯课堂,并提取报名课程(练习)

    研究QQ登录规则的话,得分析大量Javascript的加密解密,比较耗时间.自己也是练习很少,短时间成功不了.所以走了个捷径. Selenium是一个WEB自动化测试工具,它运行时会直接实例化出一个浏 ...

  7. JSON(二)——JavaScript中js对象与JSON格式字符串的相互转换

    首先我们来看一下js中JSON格式的字符串 var JSONStr1 = "{\"name\" : \"张三\"}"; 注意以下的写法不是j ...

  8. 详解Ajax请求(一)前言——同步请求的原理

    我们知道,ajax是一种异步请求的方式,想要了解异步请求,就必须要先从同步请求说起.常见的同步请求的方式是form表单的提交,我们先从一种同步请求的示例说起. 我们希望输入姓名可以从后台得到身份证号. ...

  9. Django之views系统

    Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...

  10. 安卓手机USB共享网络给PC上网

    开端 哈哈,最近我又发现了一个校园网的漏洞,但是只能手机连接,于是就想手机连接之后通过usb共享给电脑上网. 在手机上连接校园网WiFi,开启USB网络共享并且连接电脑之后,却发现电脑十分的卡顿!CP ...