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; }