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

题目大意:给定一个环,要求在这个环上截取长度为偶数且在[L,R]区间内的一段,要求平均值最大

看到环果断倍增

看到平均值最大果断二分答案

看到长度[L,R]果断单调队列

对数组维护一个前缀和,对前缀和维护单调递增的单调队列

每扫过一个数sum[i],将sum[i-L]加入单调队列,再把距离i超过R的点删掉

长度为偶数?对奇数位置和偶数位置分别维护一个单调队列即可

每次找到大于0的子串之后记录一下分母再退出就行了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
#define EPS 1e-7
using namespace std;
int n,L,R,max_num,a[M<<1];
long double sum[M<<1];
long long numerator,denominator;
int q[2][M],r[2],h[2];
bool Judge(long double x)
{
	int i;
	for(i=1;i<=n;i++)
		sum[i]=sum[i-1]+(a[i]-x);
	r[0]=r[1]=h[0]=h[1]=0;
	for(i=L;i<=n;i++)
	{
		int *q=::q[i&1],&r=::r[i&1],&h=::h[i&1],x=i-L;
		while( r-h>=1 && sum[q[r]]>sum[x] )
			q[r--]=0;
		q[++r]=x;
		while( i-q[h+1]>R )
			q[++h]=0;
		if(sum[i]-sum[q[h+1]]>=0)
			return denominator=i-q[h+1];
	}
	return false;
}
long double Bisecion()
{
	long double l=0,r=max_num;
	while(r-l>EPS)
	{
		long double mid=(l+r)/2;
		if( Judge(mid) )
			l=mid;
		else
			r=mid;
	}
	return (l+r)/2;
}
int main()
{
	int i;
	cin>>n>>L>>R;
	if(L&1) L++;
	if(R&1) R--;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		max_num=max(max_num,a[i]);
		a[i+n]=a[i];
	}
	n<<=1;
	long double ans=Bisecion();
	numerator=(long long)(ans*denominator+0.5);
	long long gcd=__gcd(numerator,denominator);
	numerator/=gcd;
	denominator/=gcd;
	if(denominator==1)
		cout<<numerator<<endl;
	else
		cout<<numerator<<'/'<<denominator<<endl;
	return 0;
}
时间: 2024-08-09 06:33:16

BZOJ 3316 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 分数规划+单调队列

[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,我们需

[bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)

偷懒直接把bzoj的网页内容ctrlcv过来了 2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1943  Solved: 1004[Submit][Status][Discuss] Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数接下来M行的01串,表示标准作文库接下来N行的01串,表示N篇作文 Output N行,每行一个整数,表示这篇作文的Lo

送礼物(二分答案+单调队列)

QUESTION: JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物.萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成一列,而且相邻的礼物之间有一种神秘的美感.于是,JYY决定从中挑选连续的一些礼物,但究竟选 哪些呢?假设礼品店一共有\(N\)件礼物排成一列,每件礼物都有它的美观度.排在第\(i\)(\(1\leq i \leq N\))个位置的礼物美观度为正整数\(A_i\).JYY决定选出其中连续的一段,即编号为礼物\(i\),\(i+1\),....,\(j-

bzoj3316 JC loves Mkk题解

3316: JC loves Mkk Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 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 Sampl

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

BZOJ 1044 HAOI2008 木棍切割 二分答案+动态规划

题目大意:给定n个连在一起的木棍.分成m+1段.使每段最大值最小,求最大值的最小值及最大值最小时切割的方案数 第一问水爆了--二分答案妥妥秒过 第二问就有些难度了 首先我们令f[i][j]表示用前j个棒♂子得到i段的方案数 诶我没打什么奇怪的符号吧 于是我们有动规方程 f[i][j]=Σf[i-1][k] (sum[j]-sum[k]<=ans,k<j) 这个最坏情况下是O(m*n^2)的,肯定挂 我们发现k的下界是单调上升的 于是我们直接令k为当前j时k的下界.开一个变量记录k~j的f值之和

BZOJ 1044 HAOI2008 木棍分割 二分答案+动态规划

题目大意:给定n个连在一起的木棍,分成m+1段,使每段最大值最小,求最大值的最小值及最大值最小时分割的方案数 第一问水爆了--二分答案妥妥秒过 第二问就有些难度了 首先我们令f[i][j]表示用前j个棒♂子得到i段的方案数 诶我没打什么奇怪的符号吧 于是我们有动规方程 f[i][j]=Σf[i-1][k] (sum[j]-sum[k]<=ans,k<j) 这个最坏情况下是O(m*n^2)的,肯定挂 我们发现k的下界是单调上升的 于是我们直接令k为当前j时k的下界,开一个变量记录k~j的f值之和

[BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】

题目链接:BZOJ - 1816 题目分析 答案具有可以二分的性质,所以可以二分答案. 验证一个答案 x 是否可行,就累加一下各种牌相对于 x 还缺少的量,如果总和超过了 x 或 m ,就不可行. 因为,当使用的joker小于等于 x 时,才可以通过合适地安排顺序使得每组牌中至多有一张 joker . 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio>