来自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. 使用Spark MLlib进行情感分析

    使用Spark MLlib进行情感分析             使用Spark MLlib进行情感分析 一.实验说明 在当今这个互联网时代,人们对于各种事情的舆论观点都散布在各种社交网络平台或新闻提要 ...

  2. GPUImage实战问题解决

    在项目中遇到了使用完GPUImage以后,内存不释放的问题,翻阅官方API,找到了解决方法: deinit{ GPUImageContext.sharedImageProcessingContext( ...

  3. Autowired注解

    package com.how2java.pojo; import org.springframework.beans.factory.annotation.Autowired; public cla ...

  4. 第四篇:用IntelliJ IDEA 搭建基于jersey的RESTful api

    编译器:Intellij IDEA 系统环境: MAC OS 相关技术:Maven.tomcat 7.jdk8 1.创建项目 首先创建一个web Application项目(这里我们打算用maven引 ...

  5. Service Worker和HTTP缓存

    很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ...

  6. redis入门(03)redis的配置

    一.配置文件 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf.你可以通过 CONFIG 命令查看或设置配置项. 二.查看修改 1.查看配置 1.1.vi redis ...

  7. GIT入门笔记(14)- 链接到远程仓库

    1.远程仓库地址https://github.com/ 2.注册远程仓库账号 3.生成ssh-key,并配置到github 由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以, ...

  8. IntelliJ IDEA开发Scala代码,与java集成,maven打包编译

    今天尝试了一下在IntelliJ IDEA里面写Scala代码,并且做到和Java代码相互调用,折腾了一下把过程记录下来. 首先需要给IntelliJ IDEA安装一下Scala的插件,在IDEA的启 ...

  9. mysql(1)—— 详解一条sql语句的执行过程

    SQL是一套标准,全称结构化查询语言,是用来完成和数据库之间的通信的编程语言,SQL语言是脚本语言,直接运行在数据库上.同时,SQL语句与数据在数据库上的存储方式无关,只是不同的数据库对于同一条SQL ...

  10. fetch简明学习

    前面的话 Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局 fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网 ...