• bzoj 4553: [Tjoi2016&Heoi2016]序列


    不得不说这道题还是很劲的(在我这个蒟蒻看来)

    摘自某神犇题解:对于每一次修改,只有序列中数值可以变成的最大值和最小值是有影响的。那么这就可以决定,有这样的一个方程

    f[i]=max(f[j])+1 其中,a[i]>=mx[j] && nm[i]>=a[j] 这样的话就保证了在所有的修改中,从f[j]转移到f[i]是始终成立的。

    那么,这样一共就有mn,mx,a三个值需要比较了。

    三位偏序,上CDQ!!题解好强!!!

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 inline int ra()
     4 {
     5     int x=0; char ch=getchar();
     6     while (ch<'0' || ch>'9') ch=getchar();
     7     while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
     8     return x;
     9 }
    10 
    11 const int maxn=100005;
    12 
    13 int c[maxn];
    14 struct node{
    15     int mx,mn,v,id;
    16 }a[maxn];
    17 int f[maxn],ans,n,m;
    18 
    19 bool cmp_mn(node a, node b) {return a.mn<b.mn;}
    20 bool cmp_id(node a, node b) {return a.id<b.id;}
    21 
    22 int lowbit(int x) {return x&(-x);}
    23 void add(int x, int val)
    24 {
    25     for (;x<maxn;x+=lowbit(x)) c[x]=max(c[x],val);
    26 }
    27 int ask(int x)
    28 {
    29     int mx=0;
    30     for (;x;x-=lowbit(x)) mx=max(mx,c[x]);
    31     return mx;
    32 }
    33 void clear(int x) {for (;x<maxn; x+=lowbit(x)) c[x]=0;}
    34 
    35 node t[maxn];
    36 void solve(int l, int r)
    37 {
    38     if (l>=r) return;
    39     int mid=l+r>>1;
    40     solve(l,mid);
    41     int tmp=l; sort(a+mid+1,a+r+1,cmp_mn);
    42     for (int i=mid+1; i<=r; i++)
    43     {
    44         while (tmp<=mid && a[tmp].v<=a[i].mn) add(a[tmp].mx,f[a[tmp].id]),tmp++;
    45         f[a[i].id]=max(f[a[i].id],ask(a[i].v)+1);
    46     }
    47     for (int i=l; i<tmp; i++) clear(a[i].mx);
    48     sort(a+mid+1,a+r+1,cmp_id);
    49     solve(mid+1,r);
    50     int L=l,R=mid+1; tmp=l;
    51     while (L<=mid && R<=r) t[tmp++]=a[L].v<a[R].v?a[L++]:a[R++];
    52     while (L<=mid) t[tmp++]=a[L++];
    53     while (R<=r) t[tmp++]=a[R++];
    54     for (int i=l; i<=r; i++) a[i]=t[i];
    55 }
    56 
    57 int main()
    58 {
    59     n=ra(); m=ra();
    60     for (int i=1; i<=n; i++) a[i].v=a[i].mn=a[i].mx=ra(),a[i].id=i,f[i]=1;
    61     for (int i=1; i<=m; i++)
    62     {
    63         int x=ra(),y=ra();
    64         a[x].mn=min(a[x].mn,y);
    65         a[x].mx=max(a[x].mx,y);
    66     }
    67     solve(1,n);
    68     for (int i=1; i<=n; i++) ans=max(ans,f[i]);
    69     cout<<ans<<endl;
    70     return 0;
    71 } 
  • 相关阅读:
    Microsoft SQL Server 简介
    windows 系统再重启后,USB口失效(鼠标、U盘都无法识别)的过程及解决方法
    Linux 系统下文件夹与文件的读写可执行权限问题
    SQL中MINUS的用法与UNION的用法
    第七讲 自定义Realm实现授权
    第六讲 授权
    第五讲 散列算法(加密算法)
    第四讲 自定义Realm来实现身份认证
    第三讲JdbcRealm及Authentication Strategy
    第二讲shiro异常及执行流程
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6792689.html
Copyright © 2020-2023  润新知