来自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. "一不小心就火了"团队采访

    团队采访 一. 采访团队 团队:一不小心就火了 采访形式:线上问答 二.采访内容 你们是怎么合理地具体分配组员里的工作的?有些团队会出现个别组员代码任务很重,个别组员无所事事的情况,你们有什么有效的方 ...

  2. 在wamp集成环境下安装laravel5.2.*框架

    虽然官方一直强烈推荐使用homestead,但是这个相对麻烦一点,所以我还是选择使用wamp集成开发环境.还有这里我只讲解windows系统下的安装,其他例如mac或linux就不写了,此文章是面向刚 ...

  3. 【技巧】Java工程中的Debug信息分级输出接口及部署模式

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  4. JavaScript查找数组中最大的值

    // 查找一个数组中最大的数 // 定义一个方法 searchMax function searchMax(arr) { // 声明一个变量MaxNumber假设为数组中最大的值arr[0]; var ...

  5. 版本名称GA的含义:SNAPSHOT->alpha->beta->release->GA

    SNAPSHOT->alpha->beta->release->GA ----------------------------------------------------- ...

  6. 一个适用于单页应用,返回原始滚动条位置的demo

    如题,最近做一个项目时,由于页面太长,跳转后在返回又回到初始位置,不利于用户体验,需要每次返回到用户离开该页面是的位置.由于是移动端项目,使用了移动端的套ui框架framework7,本身框架的机制是 ...

  7. vue组件详解(五)——组件高级用法

    一.递归组件 组件在它的模板内可以递归地调用自己, 只要给组件设置name 的选项就可以了. 示例如下: <div id="app19"> <my-compone ...

  8. IT技术有感

    今天看技术文章,spring相关的,某一个点以前每次看一直不理解, 可是不知道为什么隔了1年左右,中间什么都没做,现在却都懂了. 在看懂的那一刻,笼罩在我心上的躁动突然平静了许多,我的心这一年来前所未 ...

  9. vue中的vue-cli

    在前面的学习过程中我相信你们已经对vue有了一定的了解,现在我们来看一下vue中的vue-cli. 学习这个我们首先需要的是node环境的,如果你的网络环境慢的话建议安装淘宝镜像,在cmd中输入 np ...

  10. Android:后台给button绑定onClick事件、当返回项目到手机页面时提示是否退出APP

    上一篇文章我们学习了android通过findViewById的方式查找控件,本章将了解button控件,及btton如何绑定控件. 通过android的ui设计工具设计一个登录页面: <Rel ...