BZOJ 1293 [SCOI2009]生日礼物
【题解】
离散化+Two Pointer.
离散化的时候有些特殊姿势。
#include<cstdio> #include<vector> #include<algorithm> #define N 1000010 #define rg register using namespace std; int n,k,ans=0X7f7f7f7f,tot,r,a[N],cnt[N]; vector<int> v[N],v2[N]; inline int read(){ int k=0,f=1; char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); return k*f; } int main(){ n=read(); k=read(); for(rg int i=1;i<=k;i++){ int x=read(),y; for(rg int j=1;j<=x;j++) y=read(),v2[i].push_back(y),a[++tot]=y; } sort(a+1,a+1+n); int n2=unique(a+1,a+1+n)-a-1; n=n2; for(rg int i=1;i<=k;i++){ int x; for(rg int j=0;j<v2[i].size();j++){ x=lower_bound(a+1,a+1+n,v2[i][j])-a; v[x].push_back(i); } } tot=0; r=0; for(rg int i=1;i<=n;i++){ for(rg int j=0;j<v[i-1].size();j++){ if(cnt[v[i-1][j]]==1) tot--; if(cnt[v[i-1][j]]>0)cnt[v[i-1][j]]--; } while(r<n&&tot<k){ r++; for(rg int j=0;j<v[r].size();j++){ if(cnt[v[r][j]]==0) tot++; cnt[v[r][j]]++; } } if(tot>=k) ans=min(ans,a[r]-a[i]); //printf("i=%d r=%d tot=%d %d %d\n",i,r,tot,a[i],a[r]); } printf("%d\n",ans); return 0; }