傳送門
 
文章目錄
 
題意:
 
 
思路:
 
比較套路的一個(gè)題,我們維護(hù)一個(gè)dp[i]dp[i]dp[i]表示到了第iii行能保留的區(qū)間最多是多少。
 轉(zhuǎn)移比較明顯:dp[i]=max(dp[j])dp[i]=max(dp[j])dp[i]=max(dp[j])
 其中jjj能轉(zhuǎn)移到iii當(dāng)且僅當(dāng)他們之間有交集。
 考慮到有1e91e91e9的范圍,用線段樹來判斷的話可以動(dòng)態(tài)開點(diǎn)也可離散化,這里寫了個(gè)動(dòng)態(tài)開點(diǎn)給卡過去了。
 用線段樹維護(hù)一下區(qū)間最大值的ididid,讓后維護(hù)一個(gè)dpdpdp即可。
 
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std
;
typedef long long LL
;
typedef unsigned long long ULL
;
typedef pair
<int,int> PII
;const int N
=300010,mod
=1e9+7,INF
=0x3f3f3f3f;
const double eps
=1e-6;int n
,m
,root
,tot
;
int dis
[N
],pre
[N
];
bool st
[N
];
struct Node {int l
,r
;int id
,lid
;
}tr
[10900000];
vector
<int>v
[N
];
vector
<PII
>q
[N
];void change(int &u
,int l
,int r
,int ql
,int qr
,int id
) {if(!u
) u
=++tot
;if(dis
[id
]>dis
[tr
[u
].id
]) tr
[u
].id
=id
;if(l
>=ql
&&r
<=qr
) {if(dis
[id
]>dis
[tr
[u
].lid
]) tr
[u
].lid
=id
;return;}int mid
=(l
+r
)>>1;if(ql
<=mid
) change(tr
[u
].l
,l
,mid
,ql
,qr
,id
);if(qr
>mid
) change(tr
[u
].r
,mid
+1,r
,ql
,qr
,id
);
}void query(int &u
,int l
,int r
,int ql
,int qr
,int &id
) {if(!u
) return;if(dis
[tr
[u
].lid
]>dis
[id
]) id
=tr
[u
].lid
;if(l
>=ql
&&r
<=qr
) {if(dis
[tr
[u
].id
]>dis
[id
]) id
=tr
[u
].id
;return;}int mid
=(l
+r
)>>1;if(ql
<=mid
) query(tr
[u
].l
,l
,mid
,ql
,qr
,id
);if(qr
>mid
) query(tr
[u
].r
,mid
+1,r
,ql
,qr
,id
);
}int main()
{
scanf("%d%d",&n
,&m
);for(int i
=1;i
<=m
;i
++) {int id
,l
,r
; scanf("%d%d%d",&id
,&l
,&r
);q
[id
].pb({l
,r
});}int ans
=0; dis
[0]=0;for(int i
=1;i
<=n
;i
++) {for(auto x
:q
[i
]) {int l
=x
.X
,r
=x
.Y
;int mx
=0,id
=0;query(root
,1,1e9,l
,r
,id
);if(dis
[i
]<dis
[id
]+1) dis
[i
]=dis
[id
]+1,pre
[i
]=id
;}for(int j
=0;j
<q
[i
].size();j
++) {int l
=q
[i
][j
].X
,r
=q
[i
][j
].Y
;change(root
,1,1e9,l
,r
,i
);}}int id
=0;for(int i
=1;i
<=n
;i
++) if(ans
<dis
[i
]) ans
=dis
[i
],id
=i
;cout
<<n
-ans
<<endl
;st
[id
]=1; int cnt
=0; 	while(pre
[id
]) {id
=pre
[id
],st
[id
]=1;}for(int i
=1;i
<=n
;i
++) if(!st
[i
]) printf("%d ",i
); puts("");return 0;
}
                            總結(jié)
                            
                                以上是生活随笔為你收集整理的Codeforces Round #737 (Div. 2) D. Ezzat and Grid 线段树动态开点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。