• bzoj4553 [Tjoi2016&Heoi2016]序列


      首先记录每个点原来的数字V、最小的变化L,最大的变化R,在子序列中两个点i,j(i<j)如果相邻,应满足A[I]<=L[J] && R[I]<=A[J],然后就维护一下这个东西,有点类似二维最长不降子序列,可以用cdq分治做,复杂度O(nlognlogn)。

      代码

     1 #include<cstdio>
     2 #include<vector>
     3 #include<algorithm>
     4 #define lb(x) (x&-x)
     5 #define pb push_back
     6 using namespace std;
     7 const int N = 301010;
     8 int l[N],r[N],s[N],L[N],R[N],n,m,i,a,b,v[N],ans[N],Ans,c[N];
     9 struct g{
    10     int l,r,id;
    11 }d[N];
    12 void cc(int x,int w)
    13 {
    14     while (x<=100000)
    15     {
    16         if (w) c[x]=max(c[x],w);else c[x]=0;
    17         x+=lb(x);
    18     }
    19 }
    20 int get(int x)
    21 {
    22     int ans=0;
    23     while (x)
    24     {
    25         ans=max(ans,c[x]);
    26         x-=lb(x);
    27     }
    28     return ans;
    29 }
    30 bool cmp(g a,g b)
    31 {
    32     if (a.l==b.l)
    33         return a.id<b.id;
    34     return a.l<b.l;
    35 }
    36 void solve(int l,int r)
    37 {
    38     if (l==r)
    39     {
    40         ans[l]=max(ans[l],1);
    41         return;
    42     }
    43     int m=(l+r)>>1;
    44     solve(l,m);
    45     for (i=l;i<=r;i++)
    46     {
    47         if (i<=m)
    48         {
    49             d[i].l=v[i];
    50             d[i].r=R[i];    
    51         }
    52         else
    53         {
    54             d[i].l=L[i];
    55             d[i].r=v[i];
    56         }
    57         d[i].id=i;
    58     }
    59     sort(d+l,d+1+r,cmp);
    60     for (i=l;i<=r;i++)
    61     if (d[i].id<=m)
    62         cc(d[i].r,ans[d[i].id]); 
    63     else
    64         ans[d[i].id]=max(ans[d[i].id],get(d[i].r)+1);
    65     for (i=l;i<=r;i++)
    66     if (d[i].id<=m)
    67         cc(d[i].r,0);
    68     solve(m+1,r);
    69 }
    70 int main()
    71 {
    72     scanf("%d%d",&n,&m);
    73     for (i=1;i<=n;i++) 
    74     {
    75         scanf("%d",&v[i]);
    76         R[i]=L[i]=v[i];
    77     }
    78     for (i=1;i<=m;i++)
    79     {
    80         scanf("%d%d",&a,&b);
    81         R[a]=max(R[a],b);
    82         L[a]=min(L[a],b);
    83     }
    84     solve(1,n); 
    85     for (i=1;i<=n;i++)
    86     if (ans[i]>Ans) Ans=ans[i];
    87     printf("%d
    ",Ans);
    88 }
  • 相关阅读:
    luogu1210 回文检测
    luogu2420 让我们异或吧
    luogu4151 最大XOR和路径
    线性基
    博弈论(扯淡)
    矩阵求逆 模板
    luogu2513 逆序对数列
    洛谷4316 绿豆蛙的归宿(DAG递推/概率dp)
    1898: [Zjoi2005]Swamp 沼泽鳄鱼
    矩阵
  • 原文地址:https://www.cnblogs.com/fzmh/p/5446731.html
Copyright © 2020-2023  润新知