JZOJ5646. 【NOI2018模拟4.12】染色游戏

原创 2018年04月14日 22:09:14

题目

这里写图片描述
这里写图片描述

题目大意

给出ai,要求从中选择一些ai出来,可以不选(一定要注意)
使得这些ai是严格上升。
对于每一段连续的空位,都要付出一些代价。
要求最大化选出来的ai之和减去总代价。

题解

一种n2的做法,
fi表示ai必选的最大答案。
fi=maxfj+(ij(ij1)/2+ai(aj<ai)
在这种做法上面再进行优化,
为了去除aj<ai,就先按照a排一次序。
按照a从小到大的顺序来处理,
对于每一个fi能影响到的,是在它原来位置在它后面的还要a比它大的。
化简上面的式子,就可以发现每个fi对后面的影响就是一个一次函数。
那么就以原来序列的下标建一棵线段树,用来维护线段。

code

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 1000003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(ll &n)
{
    n=0;
    ch=G();
    while((ch<'0' || ch>'9') && ch!='-')ch=G();
    ll w=1;
    if(ch=='-')w=-1,ch=G();
    while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
    n*=w;
}

int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
ll abs(ll x){return x<0?-x:x;}
ll sqr(ll x){return x*x;}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}

struct node
{
    ll v;
    int id;
}a[N];

struct arr
{
    ll k,b;
    int l,r;
}tr[N*10],w;

ll n,m,f[N],ans,v,id,t,tot;
int opl,opr;

bool cmp(node a,node b)
{
    return a.v<b.v || (a.v==b.v && a.id<b.id);
}

void ins(int x,int l,int r)
{
    ll t1=w.k*l+w.b,t2=w.k*r+w.b;
    ll w1=tr[x].k*l+tr[x].b,w2=tr[x].k*r+tr[x].b;
    if((t1>=w1 && t2>=w2))
    {
        tr[x].k=w.k;
        tr[x].b=w.b;
        return;
    }
    if(l==r || (t1<w1 && t2<w2))return;
    int m=(l+r)>>1;
    if(!tr[x].l)tr[x].l=++tot,tr[tot].b=tr[tot].k=tr[tot].l=tr[tot].r=0;
    if(!tr[x].r)tr[x].r=++tot,tr[tot].b=tr[tot].k=tr[tot].l=tr[tot].r=0;
    ins(tr[x].l,l,m);
    ins(tr[x].r,m+1,r);
}

void work(int x,int l,int r)
{
    if(opl<=l && r<=opr)
    {
        ins(x,l,r);
        return;
    }
    int m=(l+r)>>1;
    if(opl<=m)
    {
        if(!tr[x].l)tr[x].l=++tot,tr[tot].b=tr[tot].k=tr[tot].l=tr[tot].r=0;
        work(tr[x].l,l,m);
    }
    if(m<opr)
    {
        if(!tr[x].r)tr[x].r=++tot,tr[tot].b=tr[tot].k=tr[tot].l=tr[tot].r=0;
        work(tr[x].r,m+1,r);
    }
}

ll find(int x,int l,int r,int pos)
{
    if(x==0)return 0;
    if(l==r)return pos*tr[x].k+tr[x].b;
    int m=(l+r)>>1;
    if(pos<=m)return max(pos*tr[x].k+tr[x].b,find(tr[x].l,l,m,pos));
        else return max(pos*tr[x].k+tr[x].b,find(tr[x].r,m+1,r,pos));
}

int main()
{
    freopen("paint.in","r",stdin);
    freopen("paint.out","w",stdout);

    read(n);
    for(int i=1;i<=n;i++)
        read(a[i].v),a[i].id=i;

    sort(a+1,a+1+n,cmp);
    memset(f,128,sizeof(f));ans=-n*(n+1)/2;
    tot=1;tr[tot].b=tr[tot].k=tr[tot].l=tr[tot].r=0;

    for(int i=1;i<=n;i++)
    {
        id=a[i].id;v=a[i].v;

        t=find(1,1,n,id);
        f[id]=t+v-id*(id-1)/2;
        w.k=id;w.b=f[id]-id*(id+1)/2;
        opl=id;opr=n;work(1,1,n);//ins(1,1,n);

        ans=max(ans,f[id]-(n-id)*(n-id+1)/2);
    }

    if(ans<0)P('-'),ans=-ans;
    write(ans);

    return 0;
}

JZOJ 5646. 【NOI2018模拟4.12】染色游戏

题目 分析 很显然的斜率优化,如果我们考虑忽略a那个限制的话,对于a的限制我们可以考虑cdq分治来做 代码 #include &amp;lt;bits/stdc++.h&amp;g...
  • ypxrain
  • ypxrain
  • 2018-04-12 20:28:14
  • 28

JZOJ5651. 【NOI2018模拟4.13】硬币游戏

分析 我们一组一组往里面加边,如果成环了就考虑枚举删掉哪一条边然后增广,然后就没了 代码 #include &amp;lt;bits/stdc++.h&amp;gt; #defin...
  • ypxrain
  • ypxrain
  • 2018-04-13 21:15:04
  • 9

JZOJ5608. 【NOI2018模拟3.28】Subset

题目 Data Constraint 对于 10% 的数据满足 n ≤ 20 对于 30% 的数据满足 n ≤ 2000 另有 20% 的数据满足 a i = b i 对于 100%...
  • lijf2001
  • lijf2001
  • 2018-03-29 17:10:59
  • 45

[JZOJ5620]【NOI2018模拟4.1】修炼

Description Solution 将所有商品按时间排序 那么只有这些时间点是有用的 设F[i]表示当前在第i个魂导器卖的时间,手上没有魂导器所能获得的最大魂力 N^2转移...
  • hzj1054689699
  • hzj1054689699
  • 2018-04-01 15:16:18
  • 90

【NOI2018模拟3.10】占领

Description:题解:第一问是经典的dp。先随便选一个作为根。设fif_i表示i已经被占,占领其子树需要的最少步数。转移就把i的子节点的f值从大到小排序,fi=max(fson+numson)...
  • Cold_Chair
  • Cold_Chair
  • 2018-03-14 20:21:55
  • 90

JZOJ 5627. 【NOI2018模拟4.3】paint

JZOJ 5627. 【NOI2018模拟4.3】paint DescriptionInputOutputSample Input样例输入110 10 4 1 6 4 1 6 9 9 4样例输...
  • liyizhixl
  • liyizhixl
  • 2018-04-04 09:16:40
  • 42

JZOJ5625. 【NOI2018模拟4.3】Max

题目 题解 这里的m也就是操作数很小,考虑状压操作数。 设gi,s,kgi,s,kg_{i,s,k}表示第i个数,操作状态为s,变成k的概率, 转移的时候就枚举哪一个操作还有加多少。 ...
  • lijf2001
  • lijf2001
  • 2018-04-08 12:16:08
  • 66

【NOI2018模拟3.11】猜数游戏

Description有一个数列生成器,给定正整数n,m,a,b和实数p时,它会生成一个满足以下条件的数列: (1)数列长度为n; (2)对于数列中的每个元素,它有p的概率为a*rand(),有1...
  • alan_cty
  • alan_cty
  • 2018-03-13 16:48:23
  • 64

JZOJ 5602. 【NOI2018模拟3.26】Cti & JZOJ 5057. 【GDSOI2017模拟4.13】炮塔

Description 有一个 n × m 的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭敌人. 对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一...
  • liyizhixl
  • liyizhixl
  • 2018-03-27 16:12:41
  • 45

JZOJ 5602. 【NOI2018模拟3.26】Cti

题目 有一个n*m的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭敌人。 对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它的攻击位置,当然也可以...
  • huangjingyuan107
  • huangjingyuan107
  • 2018-03-27 22:07:33
  • 17
收藏助手
不良信息举报
您举报文章:JZOJ5646. 【NOI2018模拟4.12】染色游戏
举报原因:
原因补充:

(最多只允许输入30个字)