来自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. 【iOS】Swift ?和 !(详解)

    Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值, 也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化 .如果在使用变量之前不进行初始化就会报错: [ ...

  2. Flask 蓝图(Blueprint)

    蓝图使用起来就像应用当中的子应用一样,可以有自己的模板,静态目录,有自己的视图函数和URL规则,蓝图之间互相不影响.但是它们又属于应用中,可以共享应用的配置.对于大型应用来说,我们可以通过添加蓝图来扩 ...

  3. OpenGL中怎么把世界坐标系变成屏幕坐标系

    对这个3D坐标手动进行OpenGL的四个变换,得到的结果就是屏幕上的像素坐标.前三个变换(Model, View, Projection)都是4x4矩阵,操作对象是四维向量,所以需要把(100, 10 ...

  4. 深度学习之 cnn 进行 CIFAR10 分类

    深度学习之 cnn 进行 CIFAR10 分类 import torchvision as tv import torchvision.transforms as transforms from to ...

  5. api-gateway实践(15)3.6JL分支和3.7并行改造需求

    一.名称改为"API网关" --哪个地方的名称?二.开发者视图中,API网关显示两个视图. 1. 服务分类视图:支持按照业务分为多个类别,分类方式参照应用服务化的分类:人像比对.自 ...

  6. SpringCloud的Hystrix(一) 一个消费者内的两个服务监控

    一.概念与定义 1.服务雪崩 在微服务架构中,整个系统按业务拆分出一个个服务,这些服务之间可以相互调用(RPC),为了保证服务的高可用,单个服务通常会集群部署. 但是由于网络原因或自身原因,服务并不能 ...

  7. gradle入门(1-4)多项目构建实战

    一.多项目构建 1.多项目构建概念 尽管我们可以仅使用单个组件来创建可工作的应用程序,但有时候更广泛的做法是将应用程序划分为多个更小的模块. 因为这是一个非常普遍的需求,因此每个成熟的构建工具都必须支 ...

  8. 05_Linux目录文件操作命令2_我的Linux之路

    这一节我们继续来学习Linux中对文件和目录的操作命令 mkdir 创建目录 mkdir (选项)(参数) 在Linux端可以使用mkdir来创建目录,如果你没有加其他的路径名,那么默认是在当前目录下 ...

  9. Mybatis多个参数传值方法

    第一种方案 DAO层的函数方法 Public User selectUser(String name,String area); 对应的Mapper.xml <select id="s ...

  10. 南京邮电大学java第一次实验报告

    实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...