zoukankan      html  css  js  c++  java
  • [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)

    4553: [Tjoi2016&Heoi2016]序列

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1202  Solved: 554
    [Submit][Status][Discuss]

    Description

     佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值

    可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你
    ,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可
    。注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:
    1 2 3
    2 2 3
    1 3 3
    1 1 31 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

    HINT

    Source

    用$mn_i$和$mx_i$表示$a_i$可能改变的最小/最大值,有$$j<i & a_j leq mn_i & mx_j leq a_i$$可以看出是三维偏序,CDQ分治解决。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=l; i<=r; i++)
     4 using namespace std;
     5 
     6 const int N=100100;
     7 int n,m,x,y,ans,c[N],f[N];
     8 struct P{ int a,mn,mx,x,y,id; }q[N],p[N];
     9 
    10 bool cmp(P a,P b){ return (a.x==b.x)?(a.y==b.y)?a.id<b.id:a.y<b.y:a.x<b.x; }
    11 
    12 void add(int x,int k){ for (; x<=100000; x+=x&-x) c[x]=k?max(c[x],k):0; }
    13 int que(int x){ int res=0; for (; x; x-=x&-x) res=max(res,c[x]); return res; }
    14 
    15 void solve(int l,int r){
    16     if (l==r){ f[l]=max(f[l],1); return; }
    17     int mid=(l+r)>>1; solve(l,mid);
    18     rep(i,l,r)
    19         if (q[i].id<=mid) p[i].x=q[i].a,p[i].y=q[i].mx,p[i].id=q[i].id;
    20                         else p[i].x=q[i].mn,p[i].y=q[i].a,p[i].id=q[i].id;
    21     sort(p+l,p+r+1,cmp);
    22     rep(i,l,r) if (p[i].id<=mid) add(p[i].y,f[p[i].id]); else f[p[i].id]=max(f[p[i].id],que(p[i].y)+1);
    23     rep(i,l,r) if (p[i].id<=mid) add(p[i].y,0);
    24     solve(mid+1,r);
    25 }
    26 
    27 int main(){
    28     freopen("bzoj4553.in","r",stdin);
    29     freopen("bzoj4553.out","w",stdout);
    30     scanf("%d%d",&n,&m);
    31     rep(i,1,n) scanf("%d",&q[i].a),q[i].mn=q[i].mx=q[i].a,q[i].id=i;
    32     rep(i,1,m) scanf("%d%d",&x,&y),q[x].mn=min(q[x].mn,y),q[x].mx=max(q[x].mx,y);
    33     solve(1,n);
    34     rep(i,1,n) ans=max(ans,f[i]);
    35     printf("%d
    ",ans);
    36     return 0;
    37 }
  • 相关阅读:
    OneThink友情链接插件使用!
    OneThink生成分类树方法(list_to_tree)使用!
    OneThink视图模型进行组合查询!文档组合文档详情
    Atitit.数据操作dsl 的设计 ---linq 方案
    Atitit.数据操作dsl 的设计 ---linq 方案
    Atitit.Atiposter 发帖机 信息发布器 v7 q516
    Atitit.Atiposter 发帖机 信息发布器 v7 q516
    Atitit.http连接合并组件   ConnReducerV3 新特性
    Atitit.http连接合并组件   ConnReducerV3 新特性
    Atitit.减少http请求数方案
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8579553.html
Copyright © 2011-2022 走看看