https://codeforces.ml/contest/1389/problem/F

法一:dp,所有区间按右端点排序,依次考虑“如果最后一个区间为该区间”的最优情况,它(叫做A)可以从一个“右端点比A的左端点小”的异类区间B转移过来,但是同时可以顺便把“B的右端点以右”的同类区间算上。算上同类区间可以用线段树维护:每次计算完一个区间[L,R]后,把右端点小于L的所有异类区间的dp值+1。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4  
 5 int n;
 6 const int maxn=400011;
 7  
 8 struct SEG
 9 {
10     int l,r,t;
11     bool operator < (const SEG &b) const
12     {
13         return r<b.r;
14     }
15 }seg[maxn];
16 int lisa[maxn<<1],li=0;
17  
18 int dp[maxn],contain[maxn];
19 struct SmtNode{int Max,add;};
20 struct SMT
21 {
22     SmtNode a[maxn<<2];
23     int n;
24     SMT() {n=0;}
25     void clear(int N) {n=N;}
26 //    int ls(int x) {return x<<1;}
27 //    int rs(int x) {return (x<<1)|1;}
28     #define ls(x) (x<<1)
29     #define rs(x) ((x<<1)|1)
30     void up(int x) {a[x].Max=max(a[ls(x)].Max,a[rs(x)].Max);}
31     void addsingle(int x,int v) {a[x].Max+=v; a[x].add+=v;}
32     void down(int x) {if (a[x].add>0) {addsingle(ls(x),a[x].add); addsingle(rs(x),a[x].add); a[x].add=0;} }
33     void Insert(int x,int L,int R,int p,int v)
34     {
35         if (L==R) {a[x].Max=max(a[x].Max,v); return;}
36         down(x);
37         int mid=(L+R)>>1;
38         if (p<=mid) Insert(ls(x),L,mid,p,v);
39         else Insert(rs(x),mid+1,R,p,v);
40         up(x);
41     }
42     void insert(int p,int v) {Insert(1,0,n,p,v);}
43     int QPreMax(int x,int L,int R,int p)
44     {
45         if (R<=p) return a[x].Max;
46         down(x);
47         int mid=(L+R)>>1;
48         if (p<=mid) return QPreMax(ls(x),L,mid,p);
49         return max(QPreMax(ls(x),L,mid,p),QPreMax(rs(x),mid+1,R,p));
50     }
51     int qPreMax(int p) {return QPreMax(1,0,n,p);}
52     void Add(int x,int L,int R,int ql,int qr,int v)
53     {
54         if (ql<=L && R<=qr) {addsingle(x,v); return;}
55         down(x);
56         int mid=(L+R)>>1;
57         if (ql<=mid) Add(ls(x),L,mid,ql,qr,v);
58         if (qr>mid) Add(rs(x),mid+1,R,ql,qr,v);
59         up(x);
60     }
61     void add(int L,int R,int v) {if (L<=R) Add(1,0,n,L,R,v);}
62 }s[2];
63  
64 int main()
65 {
66     scanf("%d",&n);
67     for (int i=1;i<=n;i++)
68     {
69         scanf("%d%d%d",&seg[i].l,&seg[i].r,&seg[i].t);
70         seg[i].t--;
71         lisa[++li]=seg[i].l;
72         lisa[++li]=seg[i].r;
73     }
74     sort(lisa+1,lisa+1+li); li=unique(lisa+1,lisa+1+li)-lisa-1;
75     for (int i=1;i<=n;i++)
76     {
77         seg[i].l=lower_bound(lisa+1,lisa+1+li,seg[i].l)-lisa;
78         seg[i].r=lower_bound(lisa+1,lisa+1+li,seg[i].r)-lisa;
79     }
80     sort(seg+1,seg+1+n);
81 //    for (int i=1;i<=n;i++) cout<<"NO"<<i<<' '<<seg[i].l<<' '<<seg[i].r<<' '<<seg[i].t<<endl;
82     
83     s[0].clear(li); s[1].clear(li);
84     dp[0]=0;
85     for (int i=1;i<=n;i++)
86     {
87         bool ty=seg[i].t;
88         dp[i]=s[ty^1].qPreMax(seg[i].l-1)+1;
89         s[ty].insert(seg[i].r,dp[i]);
90         s[ty^1].add(0,seg[i].l-1,1);
91 //        cout<<i<<' '<<dp[i]<<endl;
92     }
93     
94     int ans=0;
95     for (int i=1;i<=n;i++) ans=max(ans,dp[i]);
96     printf("%d\n",ans);
97     return 0;
98 }
View Code

相关文章:

  • 2021-07-11
  • 2022-03-02
  • 2022-01-01
  • 2021-05-17
  • 2022-02-02
  • 2021-08-26
猜你喜欢
  • 2022-12-23
  • 2021-05-25
  • 2021-12-23
  • 2021-05-17
  • 2021-09-25
相关资源
相似解决方案