1. 程式人生 > >bzoj4444[Scoi2015]國旗計劃

bzoj4444[Scoi2015]國旗計劃

方向 line 順時針 c++ clu esc 信息 lin mda

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≤M

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

 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 }

bzoj4444[Scoi2015]國旗計劃