zoukankan      html  css  js  c++  java
  • bzoj4553 [Tjoi2016&Heoi2016]序列

    Description

     佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可。注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:

    1 2 3
    2 2 3
    1 3 3
    1 1 3
    1 2 4
    选择子序列为原序列,即在任意一种变化中均为不降子序列在样例输入2中,所有的变化是:3 3 33 2 3选择子序列为第一个元素和第三个元素,或者第二个元素和第三个元素,均可满足要求

    Input

     输入的第一行有两个正整数n, m,分别表示序列的长度和变化的个数。接下来一行有n个数,表示这个数列原始的状态。接下来m行,每行有2个数x, y,表示数列的第x项可以变化成y这个值。1 <= x <= n。所有数字均为正整数,且小于等于100,000

    Output

     输出一个整数,表示对应的答案

    Sample Input

    3 4
    1 2 3
    1 2
    2 3
    2 1
    3 4

    Sample Output

    3

    正解:$dp$+$CDQ$分治优化。

    容易得到,$f[i]=max(f[j]+1)$,其中$j<i$,$max[j]<=a[i]$,$a[j]<=min[i]$。

    然后这就是个很裸的三维偏序,使用$CDQ$分治优化即可。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define N (200010)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define lb(x) (x & -x)
    19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    20 
    21 using namespace std;
    22 
    23 struct data{ int i,a,f,mn,mx; }q[N],qu[N];
    24 
    25 int c[N],n,m,ans,maxn=100000;
    26 
    27 il int gi(){
    28     RG int x=0,q=1; RG char ch=getchar();
    29     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    30     if (ch=='-') q=-1,ch=getchar();
    31     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    32     return q*x;
    33 }
    34 
    35 il int cmpa(const data &x,const data &y){ return x.a<y.a; }
    36 
    37 il void add(RG int x,RG int v){ for (;x<=maxn;x+=lb(x)) c[x]=max(c[x],v); return; }
    38 
    39 il void back(RG int x){ for (;x<=maxn;x+=lb(x)) c[x]=0; return; }
    40 
    41 il int query(RG int x){ RG int res=0; for (;x;x-=lb(x)) res=max(res,c[x]); return res; }
    42 
    43 il void solve(RG int l,RG int r){
    44     if (l==r){ q[l].f=max(q[l].f,1); return; }
    45     RG int mid=(l+r)>>1,t1=l-1,t2=mid;
    46     for (RG int i=l;i<=r;++i)
    47     if (q[i].i<=mid) qu[++t1]=q[i]; else qu[++t2]=q[i];
    48     for (RG int i=l;i<=r;++i) q[i]=qu[i]; solve(l,mid);
    49     for (RG int i=mid+1,x=l;i<=r;++i){
    50     for (;q[x].mx<=q[i].a && x<=mid;++x) add(q[x].a,q[x].f);
    51     q[i].f=max(q[i].f,query(q[i].mn)+1);
    52     }
    53     for (RG int i=l;i<=mid;++i) back(q[i].a); solve(mid+1,r),t1=l,t2=mid+1;
    54     for (RG int i=l;i<=r;++i)
    55     if ((q[t1].mx<=q[t2].mx && t1<=mid) || (q[t1].mx>q[t2].mx && t2>r)) qu[i]=q[t1++]; else qu[i]=q[t2++];
    56     for (RG int i=l;i<=r;++i) q[i]=qu[i]; return;
    57 }
    58 
    59 il void work(){
    60     n=gi(),m=gi(); for (RG int i=1;i<=n;++i) q[i].i=i,q[i].a=gi(),q[i].mx=q[i].mn=q[i].a;
    61     for (RG int i=1,x,y;i<=m;++i) x=gi(),y=gi(),q[x].mn=min(q[x].mn,y),q[x].mx=max(q[x].mx,y);
    62     sort(q+1,q+n+1,cmpa),solve(1,n); for (RG int i=1;i<=n;++i) ans=max(ans,q[i].f);
    63     printf("%d
    ",ans); return;
    64 }
    65 
    66 int main(){
    67     File("sequence");
    68     work();
    69     return 0;
    70 }
  • 相关阅读:
    MacOS下保护浏览器主页和默认搜索
    Tokyo Tyrant(TTServer)系列(一)-介绍和安装
    四:二叉树的镜像递归非递归求解
    Android 异常 android.os.NetworkOnMainThreadException
    Android开发学习之路--传感器之初体验
    Xcode真机调试失败:The identity used to sign the executable is no longer valid
    hdu 3068 最长回文(manacher&amp;最长回文子串)
    bzoj1030【JSOI2007】文本生成器
    HDU2082母函数模板题
    Oracle数据库远程连接配置教程
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7110089.html
Copyright © 2011-2022 走看看