Seeing that it was a ring, we pulled it into a chain very routinely.
Then we have to enumerate a starting point iii , find at least coveringi + len − 1 i+len-1i+l e n−1 The minimum number of line segments that need to be used at this position.
Since each point has to be calculated, you can consider preprocessing multiplication to calculate pi, j p_{i,j}pi,jMeans from iii start with2 j 2^j2The first position that j lines cannot cover. The transfer ispi, j = ppi, j − 1, j − 1 p_{i,j}=p_{p_{i,j-1},j-1}pi,j=ppi,j−1,j−1
p i , 0 p_{i,0} pi,0That is to cover iiThe maximum right endpoint of the line segment at point i can beset
maintainedwith the idea of difference.
Then enumerate each point, not exceeding i + len − 1 i+len-1i+l e n−Try to jump within the range of 1 (similar to the process of seeking LCA), and finally judge whether it can be completely covered.
Code
#include <bits/stdc++.h>
#define MAX 2000005
#define INF 0x3f3f3f3f
using namespace std;
struct node{
int l, r;
}a[MAX];
int m, n;
int p[MAX][24];
vector<int> v[MAX];
multiset<int> s;
int main()
{
while(cin >> m >> n){
memset(p, 0, sizeof(p));
for(int i = 1; i <= m*2; i++) v[i].clear();
for(int i = 1; i <= n; i++){
scanf("%d%d", &a[i].l, &a[i].r);
if(a[i].r < a[i].l) a[i].r += m;
v[a[i].l].push_back(a[i].r);
v[a[i].r+1].push_back(-a[i].r);
}
s.clear();
for(int i = 1; i <= m*2; i++){
for(int x:v[i]){
if(x > 0) s.insert(x);
else s.erase(s.find(-x));
}
if(!s.empty()) p[i][0] = *s.rbegin()+1;
else p[i][0] = i;
}
for(int j = 1; j <= 21; j++){
for(int i = 1; i <= m*2; i++){
p[i][j] = p[p[i][j-1]][j-1];
}
}
int ans = INF;
for(int i = 1; i <= m; i++){
int x = i, t = 0;
for(int j = 21; j >= 0; j--){
if(p[x][j] <= i+m-1) x = p[x][j], t += (1<<j);
}
if(p[x][0] > i+m-1) ans = min(ans, t+1);
}
if(ans == INF) puts("impossible");
else cout<<ans<<endl;
}
return 0;
}