cf Round 601
A.The Two Routes(BFS)
给出n个城镇,有m条铁路,铁路的补图是公路,汽车和火车同时从1出发,通过每条路的时间为1,不能同时到达除了1和n的其它点,问他们到达n点最少要用多长时间。
因为是补图,那么一定有一条路是可以直接从1到达n的。
那么我们把剩下的用bfs求一下即可。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int n, m, G[N][N], g[N][N], vis[N];
void bfs(int a[][N])
{
queue<int>q;
q.push(); vis[]=;
while (!q.empty()) {
if (vis[n]!=-) break;
int u=q.front();
q.pop();
FOR(i,,n) if (a[u][i]&&vis[i]==-) q.push(i), vis[i]=vis[u]+;
}
}
int main ()
{
int u, v;
mem(vis,-);
scanf("%d%d",&n,&m);
while (m--) scanf("%d%d",&u,&v), G[u][v]=G[v][u]=;
FOR(i,,n) FOR(j,i+,n) if (G[i][j]==) g[i][j]=g[j][i]=;
if (G[][n]==) bfs(g);
else bfs(G);
printf("%d\n",vis[n]);
return ;
}
B.Lipshitz Sequence(单调队列)
给出一个序列和q个询问。询问区间的所有子区间的lipshitz的总和是多少。
lipshitz是指对于区间[l,r], 最大的ceil(|a[i]-a[j]|/i-j).(l<=j<i<=r)。
数形结合一下,我们画下图可以发现,一个区间[l,r]内的lipshitz一定是由两个相邻的数产生的。
于是我们把|a[i+1]-a[i]|预处理出来,计算每个值能对结果产生的贡献。
于是我们需要知道这个值它最左能延伸多少,最右能延伸多少。
用两个单调队列扫两下就行了。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int a[N], b[N], q[N], l[N], r[N], head, tail; int main ()
{
int n, qq, c, d;
scanf("%d%d",&n,&qq);
FOR(i,,n) scanf("%d",a+i);
FO(i,,n) b[i]=abs(a[i+]-a[i]);
head=; tail=;
FO(i,,n) {
while (head<=tail&&b[q[tail]]<=b[i]) tail--;
l[i]=q[tail]; q[++tail]=i;
}
head=; tail=; q[tail]=n;
for (int i=n-; i>=; --i) {
while (head<=tail&&b[q[tail]]<b[i]) tail--;
r[i]=q[tail]; q[++tail]=i;
}
while (qq--) {
scanf("%d%d",&c,&d);
LL ans=;
FO(i,c,d) {
int l1=max(c,l[i]+), r1=min(d-,r[i]-);
ans+=(LL)b[i]*(i-l1+)*(r1-i+);
}
printf("%lld\n",ans);
}
return ;
}
C.Kleofáš and the n-thlon(概率DP)
有n场比赛,和m名参赛者,已知这n场比赛每个人的rank都不同。
给出你每场比赛的排名,求最终排名的期望,最终排名是比你rank之和低的人数+1.
明显的DP,令dp[i][j]表示第i场比赛时分数为j的时候人数的期望。
那么有dp[i][j]=sum(dp[i-1][k])/(m-1).(j-m<=k<=j-1&&k!=j-a[i]).
这个复杂度是O(n*m*m)。
观察发现转移的时候加的是一个区间。我们用前缀和优化转移。
复杂度O(n*m).
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int a[], flag;
double dp[][];
int main ()
{
int n, m, sum=;
scanf("%d%d",&n,&m);
FOR(i,,n) scanf("%d",a+i), sum+=a[i];
if (m==) {printf("%.10lf\n",1.0); return ;}
dp[][]=m-;
FOR(i,,n) {
flag^=;
mem(dp[flag],);
FOR(j,i,i*m) {
int l=max(j-m,i-), r=min(j-,(i-)*m);
dp[flag][j]=dp[flag^][r]-(l==?:dp[flag^][l-]);
int k=j-a[i];
if (k>=l&&k<=r) dp[flag][j]-=(dp[flag^][k]-(k==?:dp[flag^][k-]));
dp[flag][j]/=(m-);
}
FOR(j,i,i*m) dp[flag][j]+=dp[flag][j-];
}
double ans=(dp[flag][sum-]-dp[flag][n-]);
printf("%.10lf\n",ans+);
return ;
}
D.Acyclic Organic Compounds(Trie树合并)
我们算出每个节点的dif,这需要用到trie树的合并操作。
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Edge{int p, next;}edge[N<<];
int head[N], cnt=, val[N], ch[N*][], tot, size[N*];
char s[N]; void add_edge(int u, int v)
{
edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;
}
int merge(int u, int v)
{
if (u<) return v;
if (v<) return u;
int t=++tot;
size[t]=;
FOR(i,,) {
ch[t][i]=merge(ch[u][i], ch[v][i]);
if (ch[t][i]>=) size[t]+=size[ch[t][i]];
}
return t;
}
void dfs(int x, int fa)
{
FOR(i,,) ch[x][i]=-;
for (int i=head[x]; i; i=edge[i].next) {
int v=edge[i].p;
if (v==fa) continue;
dfs(v,x);
int lab=s[v]-'a'+;
ch[x][lab]=merge(ch[x][lab],v);
}
size[x]=;
FOR(i,,) if (ch[x][i]>=) size[x]+=size[ch[x][i]];
val[x]+=size[x];
}
int main ()
{
int n, u, v;
scanf("%d",&n);
FOR(i,,n) scanf("%d",val+i);
scanf("%s",s+);
FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
tot=n;
dfs(,);
int ma=, ans=;
FOR(i,,n) ma=max(val[i],ma);
FOR(i,,n) if (ma==val[i]) ans++;
printf("%d\n%d\n",ma,ans);
return ;
}
E.A Museum Robbery(待填坑)
cf Round 601的更多相关文章
- 【cf比赛记录】Codeforces Round #601 (Div. 2)
Codeforces Round #601 (Div. 2) ---- 比赛传送门 周二晚因为身体不适鸽了,补题补题 A // http://codeforces.com/contest/1255/p ...
- CF Round #551 (Div. 2) D
CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...
- CF Round #510 (Div. 2)
前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...
- UOJ #30. [CF Round #278] Tourists
UOJ #30. [CF Round #278] Tourists 题目大意 : 有一张 \(n\) 个点, \(m\) 条边的无向图,每一个点有一个点权 \(a_i\) ,你需要支持两种操作,第一种 ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2
◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...
- CF Round #600 (Div 2) 解题报告(A~E)
CF Round #600 (Div 2) 解题报告(A~E) A:Single Push 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列 #include< ...
- CF Round #580(div2)题解报告
CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...
- CF round #622 (div2)
CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...
随机推荐
- Java基础知识强化之多线程笔记04:并行和并发 区别
1. 并发 和 并行区别 (1)并发:(单核) 并发,是在同一个cpu上同时(不是真正的同时,而是看来是同时,因为cpu要在多个程序间切换)运行多个程序. 并发是指两个任务都请求运行,而处理器只能按受 ...
- Android(java)学习笔记134:Handler用法总结 和 秒表案例
一.Handler的定义: Handler主要接收子线程发送的数据, 并用此数据配合主线程更新UI,用来跟UI主线程交互用.比如可以用handler发送一个message,然后在handler的线程中 ...
- linux内核编程学习——草稿
第一章 1.1 文件IO c标准函数与系统函数的区别 FILE文件类型是一个结构体类型,包括文件描述符(inode).位置指针(f_pos).缓冲器(buffer)(8192byte). c标准文件函 ...
- Azure Powershell 创建 Internal Load Balancer
Select-AzureSubscription -SubscriptionName "订阅名称" $serviceName="云服务名称" $ilbName= ...
- PHP 使用get_class_methods()和array_diff() 兩個相同的類中方法差集
进行二次开发时,习惯一份是原封不动的,一份正在修改.在修改时,发现修改的缺少原项目中的一些方法.本打算一个方法一个方法的对比,可是这样会比较花时间,划不来,PHP可以使用get_class_metho ...
- 简单的ROT13码编码与解码
ROT13码意思是将字母左移13位.如'A' ↔ 'N', 'B' ↔ 'O','V' ↔ 'I'. 下面实现ROT13码的解码. function rot13(str) { var arr = [] ...
- js运动
一.offsetWidth / offsetHeight 获取整个块的宽度/高度,包括border 二.clientWidth / clientHeight 获取块的宽度/高度,不包括border 三 ...
- JAXB - XML Schema Types, Defining an Enumeration
If you want a data type that enumerates discrete values you should use a restriction of the schema t ...
- 【JDK源码系列】ConcurrentHashMap
并发永远是高性能的话题,而并发容器又是java中重要的并发工具,所以今天我们来分析一下Concurrent包中ConcurrentHashMap(以下简称Chashmap).普通容器在某些并发情况下的 ...
- Linux下chkconfig命令详解即添加服务以及两种方式启动关闭系统服务
The command chkconfig is no longer available in Ubuntu.The equivalent command to chkconfig is update ...