1. 程式人生 > >BZOJ4925 城市規劃

BZOJ4925 城市規劃

  對每個人行道求出移動距離在哪些區間內時其在建築物前面。現在問題即為選一個點使得其被最多的區間包含。差分即可。對建築暴力去掉重疊部分。開始時沒有去重用了nm次vector的push_back,時間大概是去重寫法的300倍,不知所措。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace
std; #define ll long long #define N 10010 #define M 1010 #define K 1000010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,m,a[N],delta[K<<1],cnt,d=K,s; struct data { int l,r; bool operator <(const data&a) const { return
l<a.l; } }b[M],c[M]; int main() { #ifndef ONLINE_JUDGE freopen("bzoj4925.in","r",stdin); freopen("bzoj4925.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=m;i++) b[i].l=read(),b[i].r=read(); for (int i=1;i<=m;i++) { bool flag=1; for (int j=1;j<=m;j++) if (i!=j&&b[j].l<=b[i].l&&b[j].r>=b[i].r) {flag=0;break;} if (flag) c[++cnt]=b[i]; } m=cnt;sort(c+1,c+m+1); cnt=0; for (int i=1;i<=m;i++) { int t=i; while (t<m&&c[t+1].l<=c[t].r) t++; cnt++;b[cnt].l=c[i].l,b[cnt].r=c[t].r; i=t; } m=cnt; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) delta[b[j].l-a[i]+K]++,delta[b[j].r+1-a[i]+K]--; cnt=0; for (int i=0;i<(K<<1);i++) { cnt+=delta[i]; if (cnt>s||cnt==s&&abs(i-K)<d) d=abs(i-K),s=cnt; } cout<<d<<' '<<s; return 0; }