bzoj3316 jc loves mkk 二分&单调队列
2015-12-22 21:43
459 查看
这道题目居然还要狗血的分数输出,真是卡精度,果断long double。
首先破环成链,然后二分答案x,用每一项减去x,那么如果有L~R的区间内且和大于0的这么一段存在,记录一下区间返回1就行了。
如何判断呢?其实只要用单调队列即可,如果i<j且sum[i]>sum[j](sum为前缀和),那么i一定不如j优,然后奇偶分开维护两个单调队列即可。
AC代码如下:
by lych
2015.12.22
首先破环成链,然后二分答案x,用每一项减去x,那么如果有L~R的区间内且和大于0的这么一段存在,记录一下区间返回1就行了。
如何判断呢?其实只要用单调队列即可,如果i<j且sum[i]>sum[j](sum为前缀和),那么i一定不如j优,然后奇偶分开维护两个单调队列即可。
AC代码如下:
#include<iostream> #include<cstdio> #define N 200005 #define ll long long #define eps 2e-5 using namespace std; int n,m,L,R,q[2] ,head[2],tail[2],a ; ll fenzi,fenmu; long double sum ; bool ok(long double x){ int i; for (i=1; i<=n; i++) sum[i]=sum[i-1]+a[i]-x; head[0]=head[1]=1; tail[0]=tail[1]=0; for (i=L; i<=n; i++){ int j=i-L,k=i&1; while (head[k]<=tail[k] && sum[j]<sum[q[k][tail[k]]]) tail[k]--; q[k][++tail[k]]=j; if (i-q[k][head[k]]>R) head[k]++; if (sum[i]-sum[q[k][head[k]]]>0){ fenmu=i-q[k][head[k]]; return 1; } } return 0; } ll gcd(ll aa,ll bb){ return (bb)?gcd(bb,aa%bb):aa; } int main(){ scanf("%d%d%d",&n,&L,&R); int i; L+=L&1; R-=R&1; long double l=0,r=0; for (i=1; i<=n; i++){ scanf("%d",&a[i]); a[i+n]=a[i]; if (a[i]>r) r=a[i]; } n<<=1; while (l+eps<r){ long double mid=(l+r)/2; if (ok(mid)) l=mid; else r=mid; } long double ans=(l+r)/2; fenzi=(ll)(ans*fenmu+0.5); ll tmp=gcd(fenzi,fenmu); fenzi/=tmp; fenmu/=tmp; if (fenmu==1) printf("%lld\n",fenzi); else printf("%lld/%lld\n",fenzi,fenmu); return 0; }
by lych
2015.12.22
相关文章推荐
- 例题5-6 UVA 540 Team Queue团体队列
- [机器学习]支持向量机及其应用---手写识别系统(SMO算法)
- 前端跨域问题解决方法
- ADC采样Q15归一化处理
- Android开发中ANR详解及解决办法
- 世界顶级软件推荐,个人亲测
- 程序9——层序遍历二叉树(从上往下打印二叉树)
- Java日期表示
- BZOJ 1010 玩具装箱 斜率优化DP
- BZOJ 1251 序列终结者
- Wince的界面切换体系——用户控件的合理使用
- 财产保险导论
- mongodb中批量将时间戳转变通用日期格式
- protobuf(Protocol Buffers)java初体验
- css资料收集
- 单例模式
- centos 6.5 阿里云 源码安装php swoole详解
- 欢迎使用CSDN-markdown编辑器
- Perl6 -1.2 操作符
- Intelij idea15 在线激活码