题目大意

  有 \(n\) 个人排成一个圈,你有 \(k\) 颗糖,你要从第 \(l\) 个人开始发糖,直到第 \(r\) 个人拿走最后一颗糖。注意这 \(n\) 个人拍成了一个圈,所以第 \(n\) 个人拿完后会轮到第 \(1\) 个人拿。第 \(i\) 个人每次拿走的糖的数量是 \(a_i\)(由你决定)。如果第 \(r\) 个人要拿两个糖且只剩下一颗糖,那么他就只会拿走这一颗。问你最多能让多少个人每次拿两颗糖。

  \(n,k\leq {10}^{11}\)

题解

  分 \(n\) 小和 \(n\) 大两部分考虑。

  如果 \(n\) 比较小,就可以枚举答案,然后判断 \(l\sim r\) 这些人能不能拿走 \(k\bmod (ans+n)\) 颗糖。

  具体来说,这些人拿走的糖的数量 \(s\) 必须满足 \(mi\leq s\leq ma\),其中

\[\begin{align}
mi&\geq ans-n+len-1\\
mi&\geq 0\\
ma&\leq ans\\
ma&\leq len\\
\end{align}
\]

  如果 \(n\) 比较大,那么就可以枚举最少那个人拿了几次糖 \((i)\)。

  记 \(k_1\) 为所有人拿的糖的数量的和,\(k_2\) 为 \(l\sim r\) 的人拿的糖的数量,那么就有

\[\begin{align}
ik_1+k_2&=k\\
mi&\geq k_1-n-n+len-1+len\\
mi&\geq len\\
ma&\leq k_1-n+len\\
ma&\leq len+len\\
mi&\leq k_2\leq ma\\
ik_1+mi&\leq k\leq ik_1+ma\\
ik_1+2len+k_1-2n-1&\leq k\\
ik_1+len&\leq k\\
ik_1+len+k_1-n&\geq k\\
ik_1+2len&\geq k\\
k_1&\leq \frac{k-2len+2n+1}{i+1}\\
k_1&\leq \frac{k-len}{i}\\
k_1&\geq \frac{k-2len}{i}\\
k_1&\geq \frac{k-len+n}{i+1}
\end{align}
\]

  然后找出这个范围内最大的 \(k_1\) 就好了。

  时间复杂度:\(O(\sqrt k)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<functional>
#include<cmath>
#include<vector>
#include<iostream>
//using namespace std;
using std::min;
using std::max;
using std::swap;
using std::sort;
using std::reverse;
using std::random_shuffle;
using std::lower_bound;
using std::upper_bound;
using std::unique;
using std::vector;
using std::cin;
using std::cout;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
void open(const char *s){
#ifndef ONLINE_JUDGE
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
void open2(const char *s){
#ifdef DEBUG
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
typedef long double ldb;
ll n,k;
ll l,r;
ll ans=-1;
ll len;
int main()
{
open("d");
cin>>n>>l>>r>>k;
len=(r>=l?r-l+1:n-l+1+r);
if(n<=1000000)
{
for(int i=n;i<=2*n;i++)
{
ll s=k%i;
if(s==0)
s=i;
s-=len;
ll mi=max(i-n-(n-len)-1,0ll);
ll ma=min(len,i-n);
if(s>=mi&&s<=ma)
ans=max(ans,i-n);
}
}
else
{
if(k>=len&&k<=2*len)
ans=max(ans,k==2*len?n:n-len+k-len+1);
for(int i=1;i<=k/n;i++)
{
ll s2=min((k-2*len+2*n+1)/(i+1),(k-len)/i);
ll s1=max((k-2*len+i-1)/i,(k-len+n+i)/(i+1));
if(s1<=s2)
ans=max(ans,s2-n);
}
}
cout<<ans<<std::endl;
return 0;
}

【CF1063D】Candies for Children 数学的更多相关文章

  1. CF1063D Candies for Children

    CF1063D Candies for Children 分类讨论题 n<=1e11, 整体上先分n<=2e6与否讨论 len长度,ans贪心的人,p就是len这一段贪心的人 n<= ...

  2. Codeforces 1063D Candies for Children

    题目大意 给定整数 $n, k, l, r$,$1\le n, k \le 10^{11}$,$1\le l, r \le n$ . 令 $ m = r - l + 1$,若 $m \le 0$,$m ...

  3. Codeforces Round #575 (Div. 3) (A. Three Piles of Candies)(数学)

    A. Three Piles of Candies time limit per test1 second memory limit per test256 megabytes inputstanda ...

  4. Codeforces1063D Candies for Children 【分类讨论】【暴力】

    题目分析: 首先要想两个暴力,一个的时间复杂度是$O(n^2)$,另一个是$O([\frac{n}{k}])$的. $n^2$的暴力可以枚举两段,一段有$i$个取两个的小朋友,一段有$j$个取两个的小 ...

  5. HDU 6126.Give out candies 最小割

    Give out candies Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  6. Codeforces Round #516(Div 2)

    比赛链接:传送门 A. Make a triangle!(简单思维) 题目大意: 给你三条边,问你最多加多少长度能使这三条边能构成三角形. 思路: 最大边小于答案加另外两条边的和. #include ...

  7. Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)

    题目链接 A. Make a triangle! 题意 让某段最少增加多少使得构成三角形 思路 让较小两段往最长段去凑 代码 #include <bits/stdc++.h> #defin ...

  8. Codeforces Round #516 (Div. 2) (A~E)

    目录 Codeforces 1064 A.Make a triangle! B.Equations of Mathematical Magic C.Oh Those Palindromes D.Lab ...

  9. CodeForces Round #516 Div2 题解

    A. Make a triangle! 暴力... 就是给你三个数,你每次可以选一个加1,问最少加多少次能构成三角形 #include <bits/stdc++.h> #define ll ...

随机推荐

  1. 《C#并发编程经典实例》学习笔记—2.2 返回完成的任务

    问题: 如何实现一个具有异步签名的同步方法. 从异步接口或基类继承代码,但希望用同步方式实现方法. 解释一下所谓的异步接口和异步基类.例如如下代码 interface IMyAsyncInterfac ...

  2. java的设计模式 - Builder模式

    Builder 模式的目的? 构造对象的方式过于复杂,不如将之抽离出来.比如,构造器参数过多 这样说也有点抽象,举个例子吧. 举个例子 比如 非常热门的消息队列RabbitMQ 的 AMQP.Basi ...

  3. 《JavaScript高级程序设计》笔记:表单脚本(十四)

    表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在JS中,表单对应的是HTMLFormElement类型.HTMLFormElement继承了HTMLElement,因而 ...

  4. 安卓9.0系统机器(亲测有效)激活Xposed框架的步骤

    对于喜欢玩手机的哥们来说,经常会用到xposed框架及其种类繁多功能无敌的模块,对于5.0以下的系统版本,只要手机能获得root权限,安装和激活xposed框架是非常简便的,但随着系统版本的持续更新, ...

  5. StackExchange.Redis中文使用文档

    StackExchange.Redis中文使用文档 Intro 最近想深入学习一些 Redis 相关的东西.于是看了看官方的项目 StackExchange,发现里面有一份文档,于是打算翻译成中文,方 ...

  6. appium+python搭建自动化测试框架_Appium元素定位(二)

    Appium元素定位: 工具:Android\android-sdk\tools    uiautomatorviewer.bat 1. id定位: self.driver.find_element_ ...

  7. win10的hyper-v共享文件夹

    win10这个奇葩,共享文件夹变得非常困难. 其他不说,关键点在于获取虚拟机的 ip,我的虚拟机系统是winxp,虚拟机本身可以上网.拿到ip,用这个ip还是无法访问\\ip 的共享文件夹,因为win ...

  8. thinkphp5.1验证器场景验证中传参的方法。

    一个场景:用户保存自己的昵称,如果已经有其他用户用了这个昵称则不允许保存,但是要排除当前用户自己,因为如果用户未作修改,新昵称和老昵称一样,是可以保存的. 因为昵称定义了唯一规则: 'name' =& ...

  9. win10安装spacemacs

    参考: https://www.cnblogs.com/e190/p/10404927.html https://blog.csdn.net/u011729865/article/details/54 ...

  10. Linux命令大杂烩

    查看linux出口IP curl ifconfig.me scp跨服务器转移文件命令 scp 文件 root@IP:/application/apache-tomcat-8.0.36      回车, ...