[hdu7168]Shallow Moon
作者:互联网
将矩形每$w$行分为一块,则染色部分即连续$h$列的前/后缀
将其离散后,对每个位置求出最长前/后缀,这可以用单调队列做到线性
将"每个位置" 和 极长的无染色块缩成一个点,显然总点数为$o(n)$
点间的边即同块内相邻两点 和 相邻两块中两点(均需判对应区间有交),显然同样为$o(n)$
时间复杂度为$o(n\log n)$(瓶颈在于离散化),可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1000005 4 #define ull unsigned long long 5 #define pii pair<int,int> 6 #define fi first 7 #define se second 8 int t,n,m,w,h,k,V,x[N],y[N],a[N],fa[N],b[N]; 9 ull ans,sz[N];pii seg[N]; 10 vector<int>lst,nlst;vector<pii>vs[N],vp[N]; 11 struct Queue{int l,r,a[N];}qs,qp; 12 int find(int k){ 13 return (k==fa[k] ? k : fa[k]=find(fa[k])); 14 } 15 void merge(int x,int y){ 16 x=find(x),y=find(y); 17 if (x!=y)fa[x]=y,sz[y]+=sz[x]; 18 } 19 int main(){ 20 scanf("%d",&t); 21 while (t--){ 22 scanf("%d%d%d%d",&n,&m,&w,&h); 23 k=V=ans=0,lst.clear(); 24 for(int i=1;i<=n;i++){ 25 scanf("%d%d",&x[i],&y[i]); 26 a[++k]=(x[i]-1)/w,a[++k]=(x[i]+w-2)/w; 27 } 28 sort(a+1,a+k+1),k=unique(a+1,a+k+1)-a-1; 29 for(int i=1;i<=k;i++)vs[i].clear(),vp[i].clear(); 30 for(int i=1;i<=n;i++){ 31 int pos=lower_bound(a+1,a+k+1,(x[i]-1)/w)-a; 32 vs[pos].push_back(make_pair(y[i],a[pos]*w+w-x[i]+1)); 33 if (x[i]%w!=1)pos++,vp[pos].push_back(make_pair(y[i],x[i]+w-a[pos]*w-1)); 34 } 35 a[0]=-1; 36 for(int i=1;i<=k;i++){ 37 if (a[i-1]+1<a[i]){ 38 fa[++V]=V,sz[V]=(ull)(a[i]-a[i-1]-1)*w*m,seg[V]=make_pair(1,m); 39 for(int j:lst)merge(j,V);lst=vector<int>{V}; 40 } 41 int len=min(a[i]*w+w,m)-a[i]*w,V0=V,lstss,lstsp; 42 qs.l=qp.l=1,qs.r=qp.r=0,nlst.clear(); 43 sort(vs[i].begin(),vs[i].end()),sort(vp[i].begin(),vp[i].end()); 44 b[0]=2,b[1]=1,b[2]=m+1; 45 for(pii j:vs[i])b[++b[0]]=j.fi,b[++b[0]]=j.fi+h; 46 for(pii j:vp[i])b[++b[0]]=j.fi,b[++b[0]]=j.fi+h; 47 sort(b+1,b+b[0]+1),b[0]=unique(b+1,b+b[0]+1)-b-1; 48 for(int j=1,x=0,y=0,z=0;j<b[0];j++){ 49 while ((x<vs[i].size())&&(vs[i][x].fi==b[j])){ 50 while ((qs.l<=qs.r)&&(vs[i][qs.a[qs.r]].se<=vs[i][x].se))qs.r--; 51 qs.a[++qs.r]=x++; 52 } 53 while ((y<vp[i].size())&&(vp[i][y].fi==b[j])){ 54 while ((qp.l<=qp.r)&&(vp[i][qp.a[qp.r]].se<=vp[i][y].se))qp.r--; 55 qp.a[++qp.r]=y++; 56 } 57 while ((qs.l<=qs.r)&&(vs[i][qs.a[qs.l]].fi+h==b[j]))qs.l++; 58 while ((qp.l<=qp.r)&&(vp[i][qp.a[qp.l]].fi+h==b[j]))qp.l++; 59 int ss=(qs.l>qs.r ? 0 : vs[i][qs.a[qs.l]].se); 60 int sp=(qp.l>qp.r ? 0 : vp[i][qp.a[qp.l]].se); 61 if (ss+sp<len){ 62 fa[++V]=V,sz[V]=(ull)(b[j+1]-b[j])*(len-ss-sp),seg[V]=make_pair(b[j],b[j+1]-1); 63 if ((V>V0+1)&&(seg[V-1].se==b[j]-1)&&(max(ss,lstss)+max(sp,lstsp)<len))merge(V-1,V); 64 if (!ss)nlst.push_back(V); 65 if (!sp){ 66 while ((z<lst.size())&&(seg[lst[z]].se<b[j]))z++; 67 while ((z<lst.size())&&(seg[lst[z]].fi<b[j+1]))merge(lst[z++],V); 68 if (z)z--; 69 } 70 lstss=ss,lstsp=sp; 71 } 72 } 73 lst=nlst; 74 } 75 if (a[k]<(m-1)/w){ 76 fa[++V]=V,sz[V]=(ull)(m-a[k]*w-w)*m,seg[V]=make_pair(1,m); 77 for(int j:lst)merge(j,V); 78 } 79 for(int i=1;i<=V;i++) 80 if (fa[i]==i)ans+=sz[i]*sz[i]; 81 printf("%llu\n",ans); 82 } 83 return 0; 84 }View Code
标签:qp,qs,int,Shallow,hdu7168,Moon,vp,fa,define 来源: https://www.cnblogs.com/PYWBKTDA/p/16524489.html