CF1146D Frog Jumping

洛谷评测传送门

题目描述

A frog is initially at position 00 on the number line. The frog has two positive integers aa and bb . From a position kk , it can either jump to position k+ak+a or k-bkb .

Let f(x)f(x) be the number of distinct integers the frog can reach if it never jumps on an integer outside the interval [0, x][0,x] . The frog doesn't need to visit all these integers in one trip, that is, an integer is counted if the frog can somehow reach it if it starts from 00 .

Given an integer mm , find \sum_{i=0}^{m} f(i)∑i=0m**f(i) . That is, find the sum of all f(i)f(i) for ii from 00 to mm .

输入格式

The first line contains three integers m, a, bm,a,b ( 1 \leq m \leq 10^9, 1 \leq a,b \leq 10^51≤m≤109,1≤a,b≤105 ).

输出格式

Print a single integer, the desired sum.

题意翻译

yyb大神仙在数轴的00位置。yyb大神仙有两个正整数a,ba,b,如果当前yyb大神仙在位置kk,yyb大神仙可以用神仙的力量将自己传送到k+ak+a或者k-bkb位置。

但是yyb大神仙感觉这样很无聊所以打算将自己限制在一段区间里。f(x)f(x)表示yyb大神仙只能在[0,x][0,x]区间里移动,从00开始能到达的整点数量。yyb大神仙想求\sum_{i=0}^mf(i)∑i=0m**f(i)。

输入输出样例

输入 #1复制

输出 #1复制

输入 #2复制

输出 #2复制

输入 #3复制

输出 #3复制

输入 #4复制

输出 #4复制

说明/提示

In the first example, we must find f(0)+f(1)+\ldots+f(7)f(0)+f(1)+…+f(7) . We have f(0) = 1, f(1) = 1, f(2) = 1, f(3) = 1, f(4) = 1, f(5) = 3, f(6) = 3, f(7) = 8f(0)=1,f(1)=1,f(2)=1,f(3)=1,f(4)=1,f(5)=3,f(6)=3,f(7)=8 . The sum of these values is 1919 .

In the second example, we have f(i) = i+1f(i)=i+1 , so we want to find \sum_{i=0}{109} i+1∑i=0109i+1 .

In the third example, the frog can't make any jumps in any case.

题解:

2019.10.28模拟赛T2 60分场

出题人@Winniechen的数据挺良心的(滑稽)

我很疑惑,为什么大佬们一开始都能想到找规律出正解。我一开始只能想到深搜,所以用一个差不多是\(O(n^2)\)的算法拿了\(10^3\)的分,假如数据是按上面说的:\(10^9\),这个算法得跑31年...

先贴一份代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int maxn=1e5+10;
int n,a,b,cnt,ans;
bool v[maxn];
void dfs(int pos,int l)
{
if(pos<0 || pos>l || v[pos])
return;
v[pos]=1;
cnt++;
dfs(pos+a,l);
dfs(pos-b,l);
}
signed main()
{
scanf("%lld%lld%lld",&n,&a,&b);
for(int i=0;i<=n;i++)
{
cnt=0;
memset(v,0,sizeof(v));
dfs(0,i);
ans+=cnt;
}
printf("%lld",ans);
return 0;
}

这就是编程的魅力,一再优化,你的31年,人家的一秒,这就是差距。国家实力就是这么被提升起来的。

接下来介绍正解:

根据我们手推样例,不难发现,会有一个路径让我们返回到出发点,这样的话就会开始循环跳来跳去。(其实这是我深搜的时候发现的),所以我们会发现一个性质:在一个区间中,如果有一个点能到达,那么这个点一定是\(\gcd(a,b)\)的倍数。

证明其实也好证:

假设我们向右跳了\(x\)次,向左跳了\(y\)次。那么就会存在一个点\(k\):

\[ax+by=k
\]

显然\(k\)一定是\(\gcd(a,b)\)的倍数。

那我们回头来求这个函数\(f(i)\),不难看出,当\(a>i\)的时候,总和就是\(a\),因为根本就动弹不了。

所以当\(n<a\)的时候就输出\(n+1\)即可(加的那个\(1\)代表\(f(0)\))。

否则我们一次性在答案上加\(a\)(一次性累加\(f(0)-f(a-1)\))。

然后我们在\([a,i]\)这个区间上寻找一个可以让路径回到出发点的点\(k\),这样的话我们就相当于处理出了一个临界值,之后的东西可以用刚才我们推出的规律处理。这个处理过程其实是一个模拟的过程,先一直往右跳,再一直往左跳,什么时候正好跳回来了就标记上(这个省略了标记的步骤,因为直接拿\(i\)记录了),最后加上跳跃的次数。

很显然,这种一次枚举跳很多步的时间复杂度是很优秀的。

这个时候跳出循环,然后按照我们发现的规律:所有可被到达的点都是\(\gcd(a,b)\)的倍数。这样处理出其他的点到\(n\)的情况。进行累加答案,输出即可。

代码:

#include<cstdio>
#define int long long
using namespace std;
int n,a,b,pos,i;
int ans,tmp=1;
int gcd(int x,int y)
{
return y?gcd(y,x%y):x;
}
signed main()
{
scanf("%lld%lld%lld",&n,&a,&b);
ans+=a;
if(n<a)
{
printf("%lld",n+1);
return 0;
}
for(i=a;i;i++)
{
while(pos+a<=i)
{
tmp+=((i-pos)/a);
pos+=((i-pos)/a)*a;
tmp+=(pos/b);
pos%=b;
if(!pos)
break;
}
if(!pos)
break;
ans+=tmp;
if(n==i)
break;
}
if(!pos)
{
int p=gcd(a,b);
int j=n-n%p;
tmp=(int)(i+j)*(j/p-i/p+1)/2;
tmp-=(int)(j+p-1-n)*(j/p);
ans+=tmp+n-i+1;
}
printf("%lld",ans);
return 0;
}

CF1146D Frog Jumping的更多相关文章

  1. [CF1146D]Frog Jumping_exgcd_堆优化dij

    Frog Jumping 题目链接:http://codeforces.com/contest/1146/problem/D 数据范围:略. 题解: 首先发现,如果$x\ge a +b$,那么所有的$ ...

  2. CodeForces Round #521 (Div.3) A. Frog Jumping

    http://codeforces.com/contest/1077/problem/A A frog is currently at the point 00 on a coordinate axi ...

  3. CF1077A Frog Jumping 题解

    Content 在一个数轴上有一个动点,初始时在 \(0\) 这个位置上,接下来有若干次操作,对于第 \(i\) 次操作: 如果 \(i\) 是奇数,那么动点往右移 \(a\) 个单位. 如果 \(i ...

  4. 杭州集训Day4

    别问我为什么没有前三天,有时间再补~ 60+60+50=170. T1 . 坐等 memset0 ( 1s 256MB )( 原题:洛谷CF1151E Number of Components ) 树 ...

  5. 【CF1146】Forethought Future Cup - Elimination Round

    Forethought Future Cup - Elimination Round 窝也不知道这是个啥比赛QwQ A. Love "A" 给你一个串,你可以删去若干个元素,使得最 ...

  6. XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix

    A. Accommodation Plan 对于已知的$K$个点,离它们距离都不超过$L$的点在树上是一个连通块,考虑在每种方案对应的离$1$最近的点统计. 即对于每个点$x$,统计离它距离不超过$L ...

  7. CodeForces Round 521 div3

    A:Frog Jumping 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen("_i ...

  8. Codeforces Forethought Future Cup Elimination Round 选做

    1146C Tree Diameter 题意 交互题.有一棵 \(n(n\le 100)\) 个点的树,你可以进行不超过 \(9\) 次询问,每次询问两个点集中两个不在同一点集的点的最大距离.求树的直 ...

  9. 2017年上海金马五校程序设计竞赛:Problem I : Frog's Jumping (找规律)

    Description There are n lotus leaves floating like a ring on the lake, which are numbered 0, 1, ..., ...

随机推荐

  1. Java之封装性

    封装概述 面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改. 封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问.要访问该类的数据,必 ...

  2. 记录libreoffice实现office转pdf(适用于windows、linux)

    由于目前的工作跟office打交道比较多,所以才有了此篇blog,需求是实现word转换pdf方便页面展示.之前lz采用的是jacob(仅支持windows)进行转换的,但是现在服务器改成linux显 ...

  3. js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素

     壹 ❀ 引 在JS开发工作中,遍历数组的操作可谓十分常见了,那么像for循环,forEach此类方法自然也不会陌生,我个人也觉得forEach不值得写一篇博客记录,直到我遇到了一个有趣的问题,我们来 ...

  4. 实验:用Unity抓取指定url网页中的所有图片并下载保存

    突发奇想,觉得有时保存网页上的资源非常麻烦,有没有办法输入一个网址就批量抓取对应资源的办法呢. 需要思考的问题: 1.如何得到网页url的html源码呢? 2.如何在浩瀚如海的html中匹配出需要的资 ...

  5. Flink JobManager 和 TaskManager 原理

    转自:https://www.cnblogs.com/nicekk/p/11561836.html 一.概述 Flink 整个系统主要由两个组件组成,分别为 JobManager 和 TaskMana ...

  6. Java反射方法总结

    1.得到构造器的方法 Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, Constructor[] getConstr ...

  7. 学习UML类图

    在类图中一共包含以下几种模型元素,分别是:类(class).接口(interface)以及类之间的关系. 1.类(class) 在面向对象编程中,类是对现象世界中一组具有相同特征的物体的抽象. 2.接 ...

  8. Python中字符的编码与解码

    1 文本和字节序列 我们都知道字符串,就是由一些字符组成的序列构成串,那么字符又是什么呢?计算机只能识别二进制的东西,那么计算机又为什么会显示我们的汉字,或者是某个字母呢? 由于最早发明使用计算机是美 ...

  9. Google_PWA_ServiceWork_渐进式 Web 应用_给应用提供离线体验

    前言:今天结识了google PWA提供的一个对移动端Web应用提供离线体验的一个功能,感觉很有用.我这里不分享自己的写法和代码.官网文档说的很详细,直接粘过来大家看吧. 推荐官网地址:你的第一个渐进 ...

  10. 配置文件_自定义section标签获取数据

    前言:为了节约时间,先只粘贴关键代码: 1-添加section标签,name为自定义标签名称,type为:命名空间+类型,程序集名称 <section name="watchModel ...