2017.9.7 JC loves Mkk 失败总结
2017-09-07 16:04
253 查看
mdzz,啥都不会、
以后碰到这种序列题一定知道要上log了
然后log不只有线段树、splay、还有二分check、
这题一开始读错了,写了错误的线段树
一开始的想法只有2的k次方一定不如2的k-1次方优,所以就可以玄学缩范围、
然后检验一个定值是o(n)的、、就是暴力
想二分、但分数怎么二分、?分母倒是有一个范围、
如果二分个数,并不满足连续性、、(9 、1 、 1、 1 、1 、9) 6比4更优、
二分分数可以转化为二分小数、、、感觉被骗了
然后就二分一个值,然后每个数-这个值,求前缀和,找到一个合法区间(>=0)就返回1 其余返回0
发现检验是可以用单调队列的、
它这个选偶数不是个提示、它没有任何价值,,就是让你奇偶分开装、、
(打了好久,不停wa,原因竟然是1、没开long long 2、变量混用3、精度+0.5*gcd、、4、没用long double)
码:
#include<iostream>
#include<cstdio>
using namespace std;
#define eps 2e-5
#define N 400005
#define ll long long
long double L=0,R=0,v
,he
,ans,v2
;
ll dui
,dui2
,i,n,a
,l,r,gs;
bool tui
;
ll gcd(ll a,ll b)
{
if(!b)return a;
return gcd(b,a%b);
}
bool check(long double o)
{
ll z1=1,z2=1,z3=1,z4=1;
v[z1]=0;
dui[z1]=0;
v2[z3]=0;
dui2[z3]=0;
for(i=1;i<=n;i++)
{//算出这个点的和
he[i]=he[i-1]+a[i]-o;
//加入新点 奇数
if(i%2)
{
if(i-l>0)v[++z2]=he[i-l];
dui[z2]=i-l;
while(z1!=z2&&v[z2]<v[z2-1])v[z2-1]=v[z2],dui[z2-1]=dui[z2],z2--;
while(dui[z1]<i-r)++z1;
if(i>=l)//计算贡献
if(he[i]-v[z1]>0)
{
gs=i-dui[z1];
return 1;
}
}else //偶数
{
if(i-l>0)v2[++z4]=he[i-l];
dui2[z4]=i-l;
while(z4!=z3&&v2[z4]<v2[z4-1])v2[z4-1]=v2[z4],dui2[z4-1]=dui2[z4],z4--;
while(dui2[z3]<i-r)++z3;
if(i>=l)//计算贡献
if(he[i]-v2[z3]>0)
{
//for(int j=1;j<=i;j++)
// {
// cout<<he[j]<<" ";
// }
// cout<<endl;
gs=i-dui2[z3];
return 1;
}
}
}
return 0;
}
int main()
{
scanf("%lld%lld%lld",&n,&l,&r);
if(l%2)l++;if(r%2)r--;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(R<a[i])R=a[i];
a[i+n]=a[i];
}
n*=2;
R+=1;
while(L+eps<R)
{
long double mid=(L+R)/2;
// cout<<L<<" "<<R<<" "<<mid<<endl;
if(check(mid))L=mid;
else R=mid;
}
ans=(L+R)/2;
ll fz=(ans)*gs+0.5;
ll fm=gs;
ll u=gcd(fz,fm);
fz/=u;
fm/=u;
if(fm==1)printf("%lld",fz);
else printf("%lld/%lld",fz,fm);
}
以后碰到这种序列题一定知道要上log了
然后log不只有线段树、splay、还有二分check、
这题一开始读错了,写了错误的线段树
一开始的想法只有2的k次方一定不如2的k-1次方优,所以就可以玄学缩范围、
然后检验一个定值是o(n)的、、就是暴力
想二分、但分数怎么二分、?分母倒是有一个范围、
如果二分个数,并不满足连续性、、(9 、1 、 1、 1 、1 、9) 6比4更优、
二分分数可以转化为二分小数、、、感觉被骗了
然后就二分一个值,然后每个数-这个值,求前缀和,找到一个合法区间(>=0)就返回1 其余返回0
发现检验是可以用单调队列的、
它这个选偶数不是个提示、它没有任何价值,,就是让你奇偶分开装、、
(打了好久,不停wa,原因竟然是1、没开long long 2、变量混用3、精度+0.5*gcd、、4、没用long double)
码:
#include<iostream>
#include<cstdio>
using namespace std;
#define eps 2e-5
#define N 400005
#define ll long long
long double L=0,R=0,v
,he
,ans,v2
;
ll dui
,dui2
,i,n,a
,l,r,gs;
bool tui
;
ll gcd(ll a,ll b)
{
if(!b)return a;
return gcd(b,a%b);
}
bool check(long double o)
{
ll z1=1,z2=1,z3=1,z4=1;
v[z1]=0;
dui[z1]=0;
v2[z3]=0;
dui2[z3]=0;
for(i=1;i<=n;i++)
{//算出这个点的和
he[i]=he[i-1]+a[i]-o;
//加入新点 奇数
if(i%2)
{
if(i-l>0)v[++z2]=he[i-l];
dui[z2]=i-l;
while(z1!=z2&&v[z2]<v[z2-1])v[z2-1]=v[z2],dui[z2-1]=dui[z2],z2--;
while(dui[z1]<i-r)++z1;
if(i>=l)//计算贡献
if(he[i]-v[z1]>0)
{
gs=i-dui[z1];
return 1;
}
}else //偶数
{
if(i-l>0)v2[++z4]=he[i-l];
dui2[z4]=i-l;
while(z4!=z3&&v2[z4]<v2[z4-1])v2[z4-1]=v2[z4],dui2[z4-1]=dui2[z4],z4--;
while(dui2[z3]<i-r)++z3;
if(i>=l)//计算贡献
if(he[i]-v2[z3]>0)
{
//for(int j=1;j<=i;j++)
// {
// cout<<he[j]<<" ";
// }
// cout<<endl;
gs=i-dui2[z3];
return 1;
}
}
}
return 0;
}
int main()
{
scanf("%lld%lld%lld",&n,&l,&r);
if(l%2)l++;if(r%2)r--;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(R<a[i])R=a[i];
a[i+n]=a[i];
}
n*=2;
R+=1;
while(L+eps<R)
{
long double mid=(L+R)/2;
// cout<<L<<" "<<R<<" "<<mid<<endl;
if(check(mid))L=mid;
else R=mid;
}
ans=(L+R)/2;
ll fz=(ans)*gs+0.5;
ll fm=gs;
ll u=gcd(fz,fm);
fz/=u;
fm/=u;
if(fm==1)printf("%lld",fz);
else printf("%lld/%lld",fz,fm);
}
相关文章推荐
- bzoj 3316 JC loves Mkk
- 2017.10.9 DZY Loves Math V 失败总结
- BZOJ3316 JC loves Mkk
- 2017.9.7 翻硬币 失败总结
- bzoj3316 jc loves mkk 二分&单调队列
- BZOJ 3316: JC loves Mkk
- BZOJ 3316 JC loves Mkk 二分答案+单调队列
- 3316: JC loves Mkk 二分答案+单调队列
- 【bzoj3316】【JC loves MKK】【单调队列+二分答案】
- 2017.10.9 DZY Loves Math VI 失败总结
- 【BZOJ 3316】JC loves Mkk 01分数规划+单调队列
- 【bzoj3316】JC loves Mkk 二分答案+单调队列
- BZOJ3316: JC loves Mkk
- BZOJ 3316: JC loves Mkk|单调队列|二分答案
- 【BZOJ3316】JC loves Mkk 分数规划+单调队列
- [bzoj3316]:JC loves Mkk
- bzoj3316: JC loves Mkk
- bzoj3316: JC loves Mkk
- BZOJ_3316_JC loves Mkk_ 二分答案 + 单调队列
- 3316: JC loves Mkk