HihoCoder 1590 : 緊張的會議室(區間最大+離散化)
阿新 • • 發佈:2018-02-18
會議室 0ms clu can 限制 兩個 closed algorithm ret
時間限制:20000ms
單點時限:2000ms
內存限制:256MB
描述
小Hi的公司最近員工增長迅速,同時大大小小的會議也越來越多;導致公司內的M間會議室非常緊張。
現在小Hi知道公司目前有N個會議,其中第i個會議的時間區間是(Si, Ei)。 註意這裏時間區間可以視為是開區間,也就是說(3, 5)和(5, 6)不會被視為是同時進行的會議。
小Hi想知道如果他新增一個會議,時間區間是(X, Y),會不會導致出現會議室不夠用的情況?
已知目前的N個會議不會導致會議室不夠用。
輸入
第一行包含兩個整數:N和M。
以下N行每行兩個整數Si和Ei,代表一個會議的時間區間。
之後一行包含一個整數Q,代表小Hi詢問的次數。
以下Q行每行包含兩個整數Xi和Yi,表示小Hi希望新增的會議時間。
對於30%的數據,1 <= N, M, Q <= 1000
對於100%的數據,1 <= N, M, Q <= 100000 0 <= Si < Ei <= 100000000 0 <= Xi < Yi <= 100000000
輸出
對於每一次詢問,輸出YES或者NO。YES代表會議室夠用,NO代表會議室不夠用。
- 樣例輸入
-
3 1 1 2 3 4 5 6 2 2 3 2 4
- 樣例輸出
-
YES NO
思路: 前綴和性質,[x,y]覆蓋,則sum[x]++,sum[y+1]--,正好題目給定的是左開右閉[x,y),則直接離散化,求區間最大。
開始用樹狀數組,一直超時。後來改成倍增就ok了。
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=1000010; intx[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn]; int tmp,tmp2,cnt,R[maxn],dp[maxn][20]; int max(int a,int b){ if(a>b) return a; return b;} int read() { int res=0; char c=getchar(); while(c>‘9‘||c<‘0‘) c=getchar(); while(c>=‘0‘&&c<=‘9‘){res=res*10+c-‘0‘; c=getchar(); } return res; } int RMQ() { for(int i=1;i<=cnt;i++) dp[i][0]=sum[i]; for(int i=1;i<20;i++) for(int j=1;j+(1<<i)<cnt;j++) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } int query(int l,int r) { int k=log2(r-l+1); return max(dp[l][k],dp[r-(1<<k)+1][k]); } int main() { int N,M,Q,i,j,Max=0; scanf("%d%d",&N,&M); for(i=1;i<=N;i++){ scanf("%d%d",&s[i],&e[i]); s[i]++; e[i]++; q[++cnt]=s[i]; q[++cnt]=e[i]; } scanf("%d",&Q); for(i=1;i<=Q;i++){ scanf("%d%d",&x[i],&y[i]); x[i]++; y[i]++; q[++cnt]=x[i]; q[++cnt]=y[i]; } sort(q+1,q+cnt+1); unique(q+1,q+cnt+1); for(i=1;i<=N;i++){ tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++; tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--; } for(i=1;i<=cnt;i++) { sum[i]+=sum[i-1]; Max=max(Max,sum[i]); } RMQ(); for(i=1;i<=Q;i++){ tmp=lower_bound(q+1,q+cnt+1,x[i])-q; tmp2=lower_bound(q+1,q+cnt+1,y[i])-q; if(query(tmp,tmp2-1)<M) printf("YES\n"); else printf("NO\n"); } return 0; }
超時代碼:
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=5000010; int x[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn]; int tmp,tmp2,cnt,R[maxn]; int max(int a,int b){ if(a>b) return a; return b;} int read() { int res=0; char c=getchar(); while(c>‘9‘||c<‘0‘) c=getchar(); while(c>=‘0‘&&c<=‘9‘){res=res*10+c-‘0‘; c=getchar(); } return res; } void add(int i,int val) { while(i<=cnt){ R[i]=max(R[i],val); i+=(-i)&i; } } int query(int l,int r) { int res=0; while(l<=r&&r){ while(r-(-r)&r>=l&&r) { res=max(res,R[r]); r-=(-r)&r; } if(r>=l) res=max(res,sum[r--]); } return res; } int main() { int N,M,Q,i,j,Max=0; scanf("%d%d",&N,&M); for(i=1;i<=N;i++){ scanf("%d%d",&s[i],&e[i]); s[i]++; e[i]++; q[++cnt]=s[i]; q[++cnt]=e[i]; } scanf("%d",&Q); for(i=1;i<=Q;i++){ scanf("%d%d",&x[i],&y[i]); x[i]++; y[i]++; q[++cnt]=x[i]; q[++cnt]=y[i]; } sort(q+1,q+cnt+1); unique(q+1,q+cnt+1); for(i=1;i<=N;i++){ tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++; tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--; } for(i=1;i<=cnt;i++) { sum[i]+=sum[i-1]; add(i,sum[i]); Max=max(Max,sum[i]); } for(i=1;i<=Q;i++){ if(Max>M) printf("NO\n"); else { tmp=lower_bound(q+1,q+cnt+1,x[i])-q; tmp2=lower_bound(q+1,q+cnt+1,y[i])-q; if(query(tmp,tmp2-1)<M) printf("YES\n"); else printf("NO\n"); } } return 0; }View Code
HihoCoder 1590 : 緊張的會議室(區間最大+離散化)