码迷,mamicode.com
首页 > 其他好文 > 详细

XJOI 园子(分数规划)

时间:2017-09-05 19:09:04      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:space   tor   splay   void   logs   bit   names   ret   its   

技术分享

技术分享

这是cxt的第一题,就这么难,都已经无力吐槽了.

听大佬们讲,这题是分数规化.

分数规划是什么?

我怎么没有听说过.

然后就只能学了一学做法

 

现将某种草药的位置处理出来,存在一个vector w[i]里

题目要求打出一个小数,很显然在0-1之间,那么就开始二分答案,条件是l+eps<=r

可是check(mid)怎么写?

是否存在l,r,使得(r-l-1)/(w[i][r]-w[i][l]-1)<=mid

将式子变形(r-mid*w[i][r])-(l-mid*w[i][l])<=1-mid

那么,令va[j]=j-mid*w[i][j];

暴扫R,那么为了尽可能满足条件,去取满足w[i][r]-w[i][l]-1>=p

的前缀最大值

然后我xxx地去写了个树状数组

结果发现只需要一个数组

 

树状数组的恶心代码:

 

#include<bits/stdc++.h>
using namespace std;
const int MAX=200000,N=100001;
const double eps=1e-9,INF=1e20;
vector<int>w[110];
double sz[N],va[N],ans;
int n,m,p;
int a[MAX];
inline void update(int x,double y,const int &limit){
    for (; x<=limit; x+=x&-x) sz[x]=max(sz[x],y);
}
inline double ask(int x){
    double res=-INF;
    for (; x; x-=x&-x) res=max(res,sz[x]);
    return res;
}
bool check(const double x,const int col){
    for (int i=1; i<=w[col].size(); i++) sz[i]=-INF;
    for (int i=0; i<w[col].size(); i++){
        va[i]=i-x*w[col][i];
        update(i+1,va[i],w[col].size());
    }
    int j=-1;
    for (int i=0; i<w[col].size(); i++){
        while (w[col][i]-w[col][j+1]-1>=p) ++j;
        if (va[i]-ask(j+1)<=1-x&&j!=-1) return 1;
    }
    return 0;
}
int main(){
    scanf("%d%d%d",&n,&m,&p);
    for (int i=0; i<n; i++) scanf("%d",&a[i]);
    for (int i=n; i<n+p; i++) a[i]=a[i-n];
    for (int i=0; i<n+p; i++) w[a[i]].push_back(i);
    for (int i=1; i<=m; i++){
        for (double l=0,r=1,mid=(l+r)/2; l+eps<=r; mid=(l+r)/2)
            if (check(mid,i)) ans=mid,r=mid; else l=mid;
        printf("%.2lf\n",ans);
    }
}

AC代码:

 

#include<bits/stdc++.h>
using namespace std;
const int MAX=200000,N=100001;
const double eps=1e-9,INF=1e20;
vector<int>w[110];
double sz[N],va[N],ans;
int n,m,p;
int a[MAX];
bool check(const double x,const int col){
    for (int i=0; i<w[col].size(); i++) sz[i]=-INF;
    for (int i=0; i<w[col].size(); i++){
        va[i]=i-x*w[col][i];
        if (i) sz[i]=max(sz[i-1],va[i]); else sz[i]=va[i];
    }
    int j=-1;
    for (int i=0; i<w[col].size(); i++){
        while (w[col][i]-w[col][j+1]-1>=p) ++j;
        if (j!=-1&&va[i]-sz[j]<=1-x) return 1;
    }
    return 0;
}
int main(){
    scanf("%d%d%d",&n,&m,&p);
    for (int i=0; i<n; i++) scanf("%d",&a[i]);
    for (int i=n; i<n+p; i++) a[i]=a[i-n];
    for (int i=0; i<n+p; i++) w[a[i]].push_back(i);
    for (int i=1; i<=m; i++){
        for (double l=0,r=1,mid=(l+r)/2; l+eps<=r; mid=(l+r)/2)
            if (check(mid,i)) ans=mid,r=mid; else l=mid;
        printf("%.2lf\n",ans);
    }
}

 

XJOI 园子(分数规划)

标签:space   tor   splay   void   logs   bit   names   ret   its   

原文地址:http://www.cnblogs.com/Yuhuger/p/7479910.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!