您的位置:首页 > 其它

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: