BZOJ1293: [SCOI2009]生日礼物

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1293

记录下每个点的颜色和上一个这一个颜色点的坐标,离散化之后枚举终点向前扫一遍。。

#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define low(x) (x&(-x)) 
#define maxn 1005000
#define inf int(1e9)
#define mm 1000000007
#define ll long long
using namespace std;
int pre[maxn],last[maxn],a[maxn],v[maxn],n,m,ans,cnt;
ll read(){
    ll x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
bool cal(int x){
    int mx=0;
    rep(i,1,m){
        while (v[last[i]]>x) {
            if (pre[last[i]]==0) return 0;
            last[i]=pre[last[i]];
        }
        if (last[i]<=x) mx=max(mx,x-v[last[i]]);
    }
    ans=min(ans,mx);
    return 1;
}
int main(){
//  freopen("in.txt","r",stdin);
    n=read(); m=read();
    rep(i,1,m){
        int t=read();
        rep(j,1,t){
            int x=read(); v[++cnt]=x; a[cnt]=x;
            pre[cnt]=last[i]; last[i]=cnt;
        }
    } 
    sort(a+1,a+1+cnt);
    ans=inf;
    down(i,cnt,1){
        if (a[i]!=a[i+1]) {
            if (!cal(a[i])) break;
        }
    }
    printf("%d\n",ans);
    return 0;
} 

 

posted on 2016-01-14 21:23  ctlchild  阅读(224)  评论(0编辑  收藏  举报

导航