• *游戏


    bzoj十一月月赛

    有n轮游戏,第i轮游戏有权值w[i](可正可负),如果选择玩第i次游戏,并且这是第k次玩这个游戏,那么会获得$w_i(k^2+ak+b)$点分数。

    你需要输出恰好玩1…n轮游戏最多能获得多少分。n<=1e5,a^2>=4b。

    首先a^2>=4b显然只是在告诉我们k^2+ak+b非负,因为如果有负的负负得正就很尴尬了。 a^2>=4b好像没啥用

    然后我们可以发现最优解是可以通过增量法构造的,就是说对于k个元素的最优解,存在一种k+1个元素的最优解比这个最优解多一个元素。证明大约如下:

    image

    那么我们可以考虑从k=0开始每次选择一个元素加进去,作为k+1的方案。

    假设加完了,那我们把每次加的元素排成一排,设f[k]表示选k个元素的方案价值,g[k]=f[k]-f[k-1],那么g应该单调不上升(由于答案是凸的)。那么我们考虑对于一个新的元素,啥时候应该把它加进去,我们发现我们可以直接追踪这个g,二分到一个位置使得g单调不上升。

    考虑这个元素加进去之后会有什么影响。容易发现一个元素插到某个位置之后,前面的g显然没有影响,对于后面的g,这个元素企图篡权夺位失败,每次失败都要后移一位。

    那么对于一个后面的g,假设它原来的rank为r,g'=g+(v[r+1]-v[r])*刚插入的w=g+(2r+a+1)*刚插入的w,r'=r+1。splay上打标记维护即可。打标记的时候需要格外小心,因为多个标记合并的时候rank改变是有先后顺序的,详见代码吧。

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string>
    #include <bitset>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <sstream>
    #include <stack>
    #include <iomanip>
    using namespace std;
    #define pb push_back
    #define mp make_pair
    typedef pair<int,int> pii;
    typedef long long ll;
    typedef double ld;
    typedef vector<int> vi;
    #define fi first
    #define se second
    #define fe first
    #define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
    #define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
    #define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
    #define es(x,e) (int e=fst[x];e;e=nxt[e])
    #define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
    #define SZ 666666
    int an=0,ch[SZ][2],fa[SZ],sz[SZ],root,rk[SZ];
    ll g[SZ],dgr[SZ],dg[SZ]; int dr[SZ];
    void sett(int x,int r,ll gr,ll gg)
    {
        if(!x) return;
        g[x]+=gr*rk[x]+gg; rk[x]+=r;
        dgr[x]+=gr; dg[x]+=gg+gr*dr[x]; dr[x]+=r;
    }
    inline void pd(int x)
    {
        sett(ch[x][0],dr[x],dgr[x],dg[x]);
        sett(ch[x][1],dr[x],dgr[x],dg[x]);
        dr[x]=dgr[x]=dg[x]=0;
    }
    void upd(int x)
    {if(!x) return; sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
    void rot(int x)
    {
        if(!fa[x]) return;
        int y=fa[x],f=fa[y],p=ch[y][1]!=x;
        fa[x]=f; fa[y]=x;
        if(f) ch[f][ch[f][1]==y]=x;
        int g=ch[x][p];
        ch[x][p]=y; ch[y][!p]=g;
        if(g) fa[g]=y;
        upd(y); upd(x); upd(f);
    }
    int ss[SZ],sn=0;
    void splay(int x,int f=0)
    {
        for(int y=x;y!=f;y=fa[y]) ss[++sn]=y;
        while(sn) pd(ss[sn--]);
        while(fa[x]!=f)
        {
            int y=fa[x];
            if(fa[y]!=f)
                (ch[fa[y]][1]==y^ch[y][1]==x)
                ?rot(x):rot(y); rot(x);
        }
        if(!f) root=x;
    }
    int n,a,b,w[SZ]; ll v[SZ];
    void ins(int x,int p,int a)
    {
        while(1)
        {
            ++sz[x]; pd(x);
            int r=(g[x]>=v[rk[x]]*ll(a));
            if(!ch[x][r])
            {ch[x][r]=p; sz[p]=1; fa[p]=x; return;}
            x=ch[x][r];
        }
    }
    ll ans[SZ];
    void dfs(int x)
    {
        if(!x) return;
        pd(x); ans[rk[x]]=g[x];
        dfs(ch[x][0]); dfs(ch[x][1]);
    }
    int main()
    {
        scanf("%d%d%d",&n,&a,&b);
        for(int i=1;i<=n;++i)
            scanf("%d",w+i),
            v[i]=(i+a)*(ll)i+b;
        sz[1]=rk[1]=root=1; g[1]=w[1]*v[1];
        for(int i=2;i<=n;++i)
        {
            ins(root,i,w[i]); splay(i);
            rk[i]=sz[ch[i][0]]+1;
            g[i]=(ll)v[rk[i]]*w[i];
            sett(ch[i][1],1,w[i]*2,(a+1)*ll(w[i]));
        }
        dfs(root);
        for(int i=2;i<=n;++i) ans[i]+=ans[i-1];
        for(int i=1;i<=n;++i)
            printf("%lld
    ",ans[i]);
    }
  • 相关阅读:
    冲刺二4
    第十四周总结
    大道至简阅读笔记02
    冲刺二3
    冲刺二2
    大道至简阅读笔记01
    冲刺二1
    第十三周总结
    第一阶段意见评价
    5月23日团队开发日志
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/8022075.html
Copyright © 2020-2023  润新知