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 } 

 

posted @ 2017-05-01 20:17  ws_ccd  阅读(163)  评论(0编辑  收藏  举报