bzoj4444[Scoi2015]國旗計劃

4444: [Scoi2015]國旗計劃

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 657  Solved: 345
[Submit][Status][Discuss]

Description

A國正在開展一項偉大的計劃——國旗計劃。這項計劃的內容是邊防戰士手舉國旗環繞邊境線奔襲一圈。這
項計劃須要多名邊防戰士以接力的形式共同完成,爲此,國土安全局已經挑選了N名優秀的邊防戰上做爲這
項計劃的候選人。
A國幅員遼闊,邊境線上設有M個邊防站,順時針編號1至M。每名邊防戰士常駐兩個邊防站,而且善於
在這兩個邊防站之間長途奔襲,咱們稱這兩個邊防站之間的路程是這個邊防戰士的奔襲區間。n名邊防戰士
都是精心挑選的,身體素質極佳,因此每名邊防戰士的奔襲區間都不會被其餘邊防戰士的奔襲區間所包含。
如今,國十安全局局長但願知道,至少須要多少名邊防戰士,才能使得他們的奔襲區間覆蓋所有的邊境線,
從而順利地完成國旗計劃。不只如此,安全局局長還但願知道更詳細的信息:對於每一名邊防戰士,在他必
須參加國旗計劃的前提下,至少須要多少名邊防戰士才能覆蓋所有邊境線,從而順利地完成國旗計劃。
 

 

Input

第1行,包含2個正整數N,M,分別表示邊防戰士數量和邊防站數量。
隨後n行,每行包含2個正整數。其中第i行包含的兩個正整數Ci、Di分別表示i號邊防戰士常駐的兩個邊防站編號,
Ci號邊防站沿順時針方向至Di號邊防站力他的奔襲區間。數據保證整個邊境線都是可被覆蓋的。
 

 

Output

輸出數據僅1行,須要包含n個正整數。其中,第j個正整數表示j號邊防戰士必須參加的前提下至少須要
多少名邊防戰士才能順利地完成國旗計劃

 

Sample Input

4 8
2 5
4 7
6 1
7 3

Sample Output

3 3 4 3

HINT

 

 n≤2×10^5,M< 10^9,1≤Ci,Di≤Mphp

https://www.cnblogs.com/clrs97/p/5304387.htmlhtml

 1 #include<bits/stdc++.h>
 2 #define N 400010
 3 using namespace std;
 4 int n,m,tot,len,mx,id[N>>1],f[N<<1],hd[N<<1];
 5 int t,q[N<<1],ans[N],b[N],l[N>>1],r[N>>1];
 6 struct edge{int v,next;}e[N<<1];
 7 void cmax(int &x,int y){if(y>x)x=y;}
 8 void adde(int u,int v){
 9     e[++tot].v=v;
10     e[tot].next=hd[u];
11     hd[u]=tot;
12 }
13 void dfs(int u){
14     q[++t]=u;
15     if(u<=len)for(int i=mx;;i++)
16     if(q[t-i]>=u+len){ans[u]=i;break;}
17     for(int i=hd[u];i;i=e[i].next)dfs(e[i].v);
18     --t;
19 }
20 int main(){
21     scanf("%d%d",&n,&m);m=0;
22     for(int i=1;i<=n;i++)
23     scanf("%d%d",&l[i],&r[i]),
24     b[++m]=l[i],b[++m]=r[i];
25     sort(b+1,b+1+m);
26     len=unique(b+1,b+1+m)-b-1;int x,y;
27     //int len=m,x,y;
28     for(int i=1;i<=n;i++){
29         id[i]=x=lower_bound(b+1,b+1+len,l[i])-b;
30         y=lower_bound(b+1,b+1+len,r[i])-b;
31         if(x<y)cmax(f[x],y),cmax(f[x+len],y+len);
32         else cmax(f[1],y),cmax(f[x],y+len),cmax(f[x+len],len<<1);
33     }
34     for(int i=1;i<=len<<1;i++)cmax(f[i],f[i-1]);
35     //for(int i=1;i<=len<<1;i++)printf("%d ",f[i]);puts("");
36     for(int i=1;i<len<<1;i++)adde(f[i],i);
37     for(int i=1;i<=len;i=f[i])++mx;--mx;
38     dfs(len<<1);
39     for(int i=1;i<=n;i++)printf("%d ",ans[id[i]]);
40     return 0;
41 }
相關文章
相關標籤/搜索