zoukankan      html  css  js  c++  java
  • P1080 国王游戏

    传送门

    考虑任意一个排队方案,对于其中某两个相邻位置 $i>0,j=i+1$,如果交换更优

    那么有 $max(A/r[i],Al[i]/r[j])>max(A/r[j],Al[j]/r[i])$,其中 $A=prod_{k=0}^{i-1}l[k]$,$l[0]$ 是国王左手的数

    因为 $A/r[i]<=Al[j]/r[i]$,$A/r[j]<=Al[i]/r[j]$,分类讨论一波发现上式等价于 $Al[i]/r[j]>Al[j]/r[i]$

    得到 $l[i]r[i]>l[j]r[j]$ 时,交换最优,所以直接按 $l*r$ 为关键字排序即可

    如果不太理解 $max$ 是怎么没的,直接按 $max(1/r[i],l[i]/r[j])>max(1/r[j],l[j]/r[i])$ 排序也行

    计算答案时要用高精度,重新学了一遍压位高精

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const ll wid=100000000;
    const int N=2e5+7;
    char ch[N];
    struct bigint
    {
        ll a[12507],len;
        bigint() { memset(a,0,sizeof(a)); len=0; }
        inline void read()
        {
            scanf("%s",ch+1);
            ll l=strlen(ch+1),t=0,k=1; len=(l+7)/8;
            for(int i=l;i;i--)
            {
                if(!((l-i)%8)){ k=1; t++; }
                a[t]+=k*(ch[i]^48); k*=10;
            }
        }
        inline void print()
        {
            if(!len) { printf("0
    "); return; }
            printf("%lld",a[len]);
            for(int i=len-1;i;i--) printf("%08lld",a[i]);
            printf("
    ");
        }
        inline bool operator < (const bigint &tmp) const {
            if(len!=tmp.len) return len<tmp.len;
            for(int i=tmp.len;i;i--) if(a[i]!=tmp.a[i]) return a[i]<tmp.a[i];
            return 0;
        }
        inline bool operator == (const bigint &tmp) const {
            return !(tmp<*this)&&!(*this<tmp);
        }
        inline bigint operator - (const bigint &tmp) const {
            bigint u; u.len=len;
            for(int i=1;i<=len;i++)
            {
                u.a[i]+=a[i]-tmp.a[i];
                if(u.a[i]<0) u.a[i]+=wid,u.a[i+1]--;
            }
            while(!u.a[u.len]&&u.len>1) u.len--;
            return u;
        }
        inline bigint operator + (const bigint &tmp) const {
            bigint u; ll x=0;
            u.len= len>tmp.len ? len : tmp.len;
            for(int i=1;i<=u.len;i++)
            {
                u.a[i]=a[i]+tmp.a[i]+x;
                x=u.a[i]/wid; u.a[i]%=wid;
            }
            while(x) u.a[++u.len]=x%wid,x/=wid;
            return u;
        }
        inline bigint operator * (const bigint &tmp) const {
            bigint u;
            for(int i=1;i<=tmp.len;i++)
                for(int j=1;j<=len;j++)
                    u.a[i+j-1]+=tmp.a[i]*a[j];//先不考虑进位
            u.len=len+tmp.len;
            for(int i=1;i<=u.len;i++) u.a[i+1]+=u.a[i]/wid,u.a[i]%=wid;//最后统一进位
            while(!u.a[u.len]&&u.len>1) u.len--;
            return u;
        }
        inline bigint operator / (const int &tmp) const {//整除
            bigint u; u.len=len; ll x=0;
            for(int i=len;i;i--)
            {
                x*=wid; x+=a[i];
                u.a[i]=x/tmp; x%=tmp;
            }
            while(!u.a[u.len]&&u.len>1) u.len--;
            return u;
        }
    }A,B,C,ans;
    int n;
    struct dat{
        int x,y;
        inline bool operator < (const dat &tmp) const {
            return x*y<tmp.x*tmp.y;
        }
    }d[N];
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<=n;i++) scanf("%d%d",&d[i].x,&d[i].y);
        sort(d+1,d+n+1);
        A.a[1]=d[0].x; A.len=1;
        for(int i=1;i<=n;i++)
        {
            C=A/d[i].y; if(ans<C) ans=C;
            B.a[1]=d[i].x; B.len=1; A=A*B;
        }
        ans.print();
        return 0;
    }
  • 相关阅读:
    JQuery Table 合并单元格-解决Bug版本
    SQLServer当数据导入平面文件
    【BZOJ1294】[SCOI2009]围豆豆Bean 射线法+状压DP+SPFA
    【BZOJ3590】[Snoi2013]Quare 状压DP
    【BZOJ4036】[HAOI2015]按位或 FWT
    【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分
    【CF603E】Pastoral Oddities cdq分治+并查集
    【CF891E】Lust 生成函数
    【CF618G】Combining Slimes 概率+矩阵乘法
    【CF633H】Fibonacci-ish II 莫队+线段树
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11367907.html
Copyright © 2011-2022 走看看