[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

 

posted @ 2022-07-27 13:02  PYWBKTDA  阅读(70)  评论(0编辑  收藏  举报