bzoj3316 JC loves Mkk题解

3316: JC loves Mkk

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 979  Solved: 316
[Submit][Status][Discuss]

Description

Input

第1行,包含三个整数。n,L,R。
第2行n个数,代表a[1..n]。

Output

仅1行,表示询问答案。
如果答案是整数,就输出整数;否则,输出既约分数“P/Q”来表示。

Sample Input

5 3 4

3 1 2 4 5

Sample Output

7/2

HINT

1≤L≤R≤n≤10^5,0≤ai≤10^9,保证问题有解,数据随机生成

  这道题其实挺有意思的,既约分数这一点恐怕卡住了无数想打二分的像我一样的蒟蒻,然而,如果我们观察到问题的本质我们就可以抛开既约分数对于二分答案的限制。

  所以,为了方便,我们先假设这道题只是让我们输出小数,那么假设我们二分出来的答案是x,l为我们选择的左边界则:

    sum[i]-sum[l-1]/(i-l+1)>=x   (L<=i-l+1<=R (i-l+1)%2==0)

  将式子化简可得sum[i]-i*x>=sum[l-1]-(l-1)*x那么每一个点所提供的信息在二分答案确定后也就可以确定了。值得注意的是由于题目偶数的限制,我们需要准备两个单调队列去满足这一条件,利用滚动数组即可,同时,我们也应注意到,我们实际要求的是sum[l-1]-(l-1)*x最小,对于l自己本身并无要求,所以我们单调队列存的实际是l-1的信息。

  现在,除了既分约数基本这道题解决完了。我们可以注意到,对于每次check二分的值成功时他所对应的答案一定是递增的,所以我们完全可以抛开我们二分的值,直接现求当前答案,这样就可以很好的解决既分约数对于二分答案的限制了。

  

 1 #pragma GCC optimze("O3")
 2 #include<iostream>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<cmath>
 9 #include<map>
10 #include<vector>
11 #define N 100005
12 using namespace std;
13 int n,L,R;
14 long long a[2*N],sum[N*2],mx;
15 int q[2][N*2];
16 int hea[2],en[2];
17 long long ansa,ansb;
18 long long gcd(long long x,long long y)
19 {
20     if(y==0)return x;
21     return gcd(y,x%y);
22 }
23 bool check(double x)
24 {
25     memset(q,0,sizeof(q));
26     hea[0]=hea[1]=1,en[0]=en[1]=0;
27     int now=1,la=0;
28     for(int i=L;i<2*n;i++)
29     {
30         swap(now,la);
31         while(hea[now]<=en[now]&&sum[q[now][en[now]]]-(double)(q[now][en[now]])*x>sum[i-L]-(double)(i-L)*x) en[now]--;
32         en[now]++;
33         q[now][en[now]]=i-L;
34         if(i>R)
35             while(hea[now]<=en[now]&&q[now][en[now]]<i-R)hea[now]++;
36         if(sum[i]-sum[q[now][hea[now]]]>=(double)(i)*x-(double)(q[now][hea[now]])*x)
37         {
38             ansa=sum[i]-sum[q[now][hea[now]]];
39             ansb=i-q[now][hea[now]];
40             long long t=gcd(ansa,ansb);
41             ansa/=t;
42             ansb/=t;
43             return 1;
44         }
45     }
46     return 0;
47 }
48 int main()
49 {
50     scanf("%d%d%d",&n,&L,&R);
51     if(L%2)L++; if(R%2)R--;
52     for(int i=1;i<=n;i++)
53     {
54         scanf("%lld",&a[i]);
55         a[i+n]=a[i];
56         mx=max(mx,a[i]);
57     }
58     for(int i=1;i<n*2;i++)
59         sum[i]+=sum[i-1]+a[i];
60     double li=0,ri=mx;
61     while(ri-li>1e-6)
62     {
63         double mid=(li+ri)/2;
64         if(check(mid)) li=mid;
65         else ri=mid;
66     }
67     if(ansb!=1)
68         printf("%lld/%lld\n",ansa,ansb);
69     else
70         printf("%lld\n",ansa);
71     return 0;
72 }

时间: 2024-10-25 10:07:51

bzoj3316 JC loves Mkk题解的相关文章

bzoj3316 JC loves Mkk 二分答案 单调队列

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3316 题意:给出一个环,求出长度在$L~R$之间任意偶数的一个序列,使得这个序列的平均值最大. 看到分数就知道这题不可做-- 好啦言归正传--这道题应该怎么做呢--直接上$PoPoQQQ$大爷的语录: 看到环果断倍增 看到平均值最大果断二分答案 看到长度[L,R]果断单调队列 没错就是这样--平均值这个东西其实就是要这么瞎搞--二分答案,然后给每个元素"咔嚓"一下去掉二分的值,之后

BZOJ3316 JC loves Mkk

首先断环成链,变成两倍长度. 然后二(fen)分(shu)答(gui)案(hua),查看答案为ans的长度在[L, R]之间的链存不存在. 我们可以维护前缀和,用单调队列O(n)判断是否和大于0 又学习了个黑科技...::x表示全局变量x... 1 /************************************************************** 2 Problem: 3316 3 User: rausen 4 Language: C++ 5 Result: Acce

【BZOJ3316】JC loves Mkk 分数规划+单调队列

[BZOJ3316]JC loves Mkk Description Input 第1行,包含三个整数.n,L,R.第2行n个数,代表a[1..n]. Output 仅1行,表示询问答案.如果答案是整数,就输出整数:否则,输出既约分数“P/Q”来表示. Sample Input 5 3 4 3 1 2 4 5 Sample Output 7/2 HINT 1≤L≤R≤n≤10^5,0≤ai≤10^9,保证问题有解,数据随机生成 题解:直接二分答案,然后每个糖果的权值都变成a[i]-mid,我们需

BZOJ 3316 JC loves Mkk 二分答案+单调队列

题目大意:给定一个环,要求在这个环上截取长度为偶数且在[L,R]区间内的一段,要求平均值最大 看到环果断倍增 看到平均值最大果断二分答案 看到长度[L,R]果断单调队列 对数组维护一个前缀和,对前缀和维护单调递增的单调队列 每扫过一个数sum[i],将sum[i-L]加入单调队列,再把距离i超过R的点删掉 长度为偶数?对奇数位置和偶数位置分别维护一个单调队列即可 每次找到大于0的子串之后记录一下分母再退出就行了 #include <cstdio> #include <cstring>

【题解】Luogu P2397 yyy loves Maths VI (mode)

problem 很有意思的一道题 Solution 初看此题毫无头绪,2.2mb太丧心病狂了 再看题目,注意到重要性质:众数个数大于一半 看完题解之后想到使用一个方法:摩尔投票法 摩尔投票法是啥玩意? 考虑一段序列,其中众数的个数超过一半 每一轮投票,从序列中选出两个不同的数,丢弃 无法再进行投票后,最终一定剩下大于等于一个全部相同的数,即众数 会不会有剩两种或以上不同的数? 不会.根据定义,此时我们还可以再进行一次投票 很好,可是要怎么用到题目上面? 十分极限的空间限制要求我们的算法空间复杂度

$题解 P2394 【yyy loves Chemistry I】$

$ P2394 ?yyy ?loves ? Chemistry ?I$ 感觉这道题没这么难啊?本蒟蒻还是很疑惑,为什么评分为普及+/提高呢? 好了,废话不多说,一起愉快地做题吧! \[First:\text{输入}\] 我相信,第一次做题的时候,大多数的人都会这么输入 scanf("%Lf",&a); 但这么输入是错误的,为什么呢?因为\(a\)的精度你无法确定,而long double的精度只有\(18-19\)位. 那怎么办呢?别急别急,喝口茶慢慢说,好在scanf可以强制

题解 CF446C 【DZY Loves Fibonacci Numbers】

# 题解 CF446C这是一道数据结构题. 我们先翻译下题目: 给你一个n,给你一个长度为n的序列,给你一个m,给你m此操作,包括区间修改和查询,修改为在一个区间内每个数加上他所对应的斐波那契数,查询为查询区间和. 一看到区间修改和区间查询,我们就可以知道这是一道线段树的题目(不要问我怎么知道的,~~我也想知道~~) 进入正题: 我们一定要找到一种方法,维护区间和. 我们可以先把斐波那契数列的每一项拆开,找规律,我们会发现: $$f_1=f_1,f_2=f_2$$$$f_3=f_1+f_2,f_

newcoder Tachibana Kanade Loves Probability(小数点后第k位)题解

题意:题目链接立华奏在学习初中数学的时候遇到了这样一道大水题: “设箱子内有 n 个球,其中给 m 个球打上标记,设一次摸球摸到每一个球的概率均等,求一次摸球摸到打标记的球的概率” “emmm...语言入门题” 但是她改了一下询问方式:设最终的答案为 p ,请输出 p 小数点后 K1K1 到 K2K2 位的所有数字(若不足则用 0 补齐) 思路:上次好像蓝桥杯看到过,暴力骗了80分没做了.还是自己菜啊,显然我们模拟除法的过程是 m * 10 % n * 10 % n * 10 % n......

【BZOJ3563/3569】DZY Loves Chinese II 线性基神题

[BZOJ3563/3569]DZY Loves Chinese II Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以修能. 遂降临于OI界,欲以神力而凌♂辱众生. 今Dzy有一魞歄图,其上有N座祭坛,又有M条膴蠁边. 时而Dzy狂WA而怒发冲冠,神力外溢,遂有K条膴蠁边灰飞烟灭. 而后俟其日A50题则又令其复原.(可视为立即复原) 然若有祭坛无法相互到达,Dzy之神力便会大减,于是欲知其是否连通. Input 第