【纪中集训2019.08.20】【JZOJ6310】Global warming

题目链接

题意:

  给出一个长度为$n$的序列$\{a_n\}$。

  已知一个正整数$x$,你有一次机会指定区间$[l,r]$,令$\forall i\in [l,r],\;a_i=a_i+d\,(|d|\le x)$。

  求最大化的最长上升子序列的长度。

  $1 \le n \le 2 \times 10^5 , \quad 1 \le a_i,x \le 10^9$且均为正整数。

分析:

  可以很容易发现三个性质:

  性质一:抬升$[l,r]$不优于抬升$[l,n]$,降低$[l,r]$不优于降低$[1,l]$。

  性质二:降低$[1,p]$等价于抬升$[p+1,n]$。

  性质三:抬升/降低$k$不优于抬升/降低$x$。

  由此很容易想到分成两块求部分答案,再拼成总答案。

  但这并不是简单地把向左/右拓展的上升子序列或者它们的前/后缀最大值在某个分割点加起来。怎么办呢?

  考虑在从左向右做$LIS$时加上一些限制,即$a_i$必须不超过$\mathop{min} \limits _{j=i+1} ^n \{ a_j \}$才能加入$LIS$中。

  这个做法显然是错误的,因为这样会遗漏很多贡献。如果坚持用“限制法”来做,那么$i$每移动一次,限制更新了,都要把之前的全部重算一次,这样才能正确。

  等一下,是我们的思路出了问题吗?有这么复杂吗?

  让我们冷静一下,现在我们在求什么?

  一些“左拼图”候选。

  “限制法”尝试让现在求得的“左拼图”能对上所有“右拼图”,这是不现实的。

  所以我们应该考虑的是怎么样让对应长度的“拼图”“契合”。应该让$a_i$到左侧的$LIS$中去找到位置。

  来一个规范一点的定义:

  设$f_i$表示将$[1,i-1]$降低时,以$a_i$为结尾的最长上升子序列长度。

  那么我们正着做$LIS$时把每个$a_i-x$放入单调数组里,当$2\le i\le n$时$a_i$在单调数组里的合法位置就是$f_i$了。

  之后再反着做$LIS$,设单调数组在$i$时的长度为$l_i$,那么答案是$max \{ \, \mathop{max}\limits^{n}_{i=2}\{ f_i + l_i \} \, , \, l_1 \, \}$。

实现(100分):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define IL inline
using namespace std;
const int N=2e5;
const int inf=0x3f3f3f3f;

    int n,x,a[N+3];
    int f[N+3];

IL bool cmp1(int p,int q){
    return p>=q;

}

IL bool cmp2(int p,int q){
    return p<=q;

}

IL int bins(int *a,int l,int r,int x,bool cmp(int p,int q)){
    int mid,ans=0;
    while(l<=r){
        mid=(l+r)>>1;
        if(cmp(a[mid],x)){
            ans=mid;
            r=mid-1;

        }
        else
            l=mid+1;

    }
    return ans;

}

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

    scanf("%d%d",&n,&x);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);

    int s[N+3],k;
    memset(s,0x3f,sizeof s);
    s[0]=-inf;    k=0;
    for(int i=1;i<=n;i++){
        f[i]=max(0,bins(s,1,k+1,a[i],cmp1)-1);
        int p=bins(s,1,k+1,a[i]-x,cmp1);
        s[p]=a[i]-x;    k=max(k,p);

    }

    int ans;
    memset(s,0,sizeof s);
    s[0]=inf;
    k=ans=0;
    for(int i=n;i>=1;i--){
        int p=bins(s,1,k+1,a[i],cmp2);
        s[p]=a[i];    k=max(k,p);
        ans=max(ans,p+f[i]);

    }

    printf("%d",ans);

    return 0;

}

小结:

  显然性质$\rightarrow$化归拆解问题$\rightarrow$合适地拼出答案。

原文地址:https://www.cnblogs.com/Hansue/p/11385603.html

时间: 2024-11-06 07:30:39

【纪中集训2019.08.20】【JZOJ6310】Global warming的相关文章

【纪中集训2019.3.20】河

题目 描述 给出\(n\)条河流,每条河流是形式为\(k_{i}x+b_{i}\)的一次函数且只有\(x\)轴正半轴的部分: 河流的污染部分和另外一条河流的干净部分交汇,干净的部分会被污染: 有若干个工厂要建在\(b_{i}\)处,问有多少种方案使得所有的河流在无穷远处被污染: 答案对\(1e9+7\)取模 范围 $1 \le N \le 5 \times 10^5 ? ?, ??|k_{i}|,|b_{i}| \le 10^9 $ 保证\(b_{i}\)互不相同: 题解 需要先找到可以被一条河

【纪中集训2019.08.21】【JZOJ6315】数字

题目链接 题意: 设$s(i)$为将$1\sim i$看做字符串后依次连接形成的串.给定正整数$n$,求最小的$i$使得$n$是$s(i)$的字串.$T$组数据. $n\le 10^{17}, \; t\le 10^4$ 分析: 不能模拟$s(i)$的组成过程来找答案,时间不能承受. 也不能预处理$s(k)$,空间不能承受. 那就只能在$n$上找答案. 以下把数字当成字面量来讨论,更方便. 同时,这里讨论的前缀和后缀不包括本身. 思考一下,答案分为三种: 1.$ans=n$ 2.$n$由$ans

纪中集训2019.11.08

A.三角形计数 题目链接 题意: 咕 分析: 咕 实现: 咕 小结: 咕 B.Isaac 题目链接 题意: 咕 分析: 咕 实现: 咕 小结: 咕 C.字符消除 题目链接 题意: 咕 分析: 咕 实现: 咕 小结: 咕 当天总结: 咕 原文地址:https://www.cnblogs.com/Hansue/p/11826709.html

【纪中集训2019.3.12】Mas的仙人掌

题意: ? 给出一棵\(n\)个点的树,需要加\(m\)条边,每条边脱落的概率为\(p_{i}\) ,求加入的边在最后形成图中仅在一个简单环上的边数的期望: 题解: 考虑每一条边的贡献是\((1-p_{i})*\Pi_{j}p_{j}(j!=i)\),这里\(j\)和\(i\)不能同时加入: 一条加入的边可以看成一条树上路径 ,即求所有和路径\(i\)相交的路径\(j\)的\(p_{j}\)的乘积: 将一条树上的链\((u,v)\)拆成两条\((u,lca)\)和\((v,lca)\); 这样会

【纪中集训2019.3.29】整除分块

题目 描述 ? 本题的背景是整除分块: ? 定义一个数列$a_{n,i} ? = ?\lfloor \frac{n}{i} \rfloor $ ; ? 求$\sum_{i=l}^{r} mex(a_n) $ ; ? 其中\(mex\)表示序列中最小的没有出现过的自然数: ? 答案对\(998244353\)取模 : 范围 ? \(1 \le T \le 65536 \ , \ 1 \le l ,r \le 10^{36}\) : ? 评测系统支持使用 $ _ _ int218 $ ,但是不能直接

【纪中模拟2019.08.03】【JZOJ1308】取数游戏

题目链接 题意: N个正整数围成一圈,规则如下: •两个玩家轮流取数:•先手玩家取任意一个数x:•从第二步开始当前玩家只能取x(上一玩家取的数)相邻的数:•直到取完所有的数,游戏结束:•取得较多奇数的玩家获胜. 保证双方都采取最优策略的同时,计算先手有多少种取法获胜. $1\le N\le 10^2,\quad 1\le x\le 10^3$ 实现(100分): 因为笔者不会SG函数,所以如果有绕弯子的描述请谅解. 分析博弈过程,有$2^n$种形势,按博弈写程序会T. 考虑DP,貌似取数的过程有

【纪中模拟2019.08.17】【JZOJ3503】粉刷

题目链接 题意: 给定一个$N\times M$的$01$矩阵,要求覆盖所有$1$的位置,求最小操作次数.一次操作,可以竖着覆盖连续的最多$C$列,或者横着覆盖连续的最多$R$行. $1\le\;N,\;M,\;R,\;C\le\;15$ 分析: 数据范围较小,考虑枚举. 但是不能盲目地同时枚举覆盖行.覆盖列的操作,因为这样的枚举是$O (2^{2N})$的,会$T$. 考虑枚举覆盖行的操作,枚得一种方案之后贪心地计算覆盖列的操作,完成. 总的时间复杂度$O (N^3\times 2^N)$.

纪中集训2019.11.06

A.困难的图论 题目链接 题意: 给出由$n$个点和$m$条边构成的无向连通图,要求选出一些边.一条边被选中当且仅当它恰好被一个简单环经过. 一个环被称为简单环,当且仅当这个环上的所有点都只在这个环中被经过了一次. 输出这些边的编号的异或和.边从$1$开始编号. $1\le n\le 10^6,\;1\le m\le min\{10^6,n\times (n+1) /2\}$. 分析: 注意:一个图可能有很多简单环,题目要求选中所有简单环上的边.考场上我就是这一点搞错了.(其实搞对了也很可能做不

纪中集训2019.11.07

A.极好的问题 题目链接 题意: 咕 分析: 咕 实现: 咕 小结: 咕 B.背包问题 题目链接 题意: 咕 分析: 咕 实现: 咕 小结: 咕 C.子树问题 题目链接 题意: 咕 分析: 咕 小结: 咕 当天总结: 咕 原文地址:https://www.cnblogs.com/Hansue/p/11811824.html