1. 程式人生 > >HDU 5126 stars (四維偏序+樹狀數組)

HDU 5126 stars (四維偏序+樹狀數組)

ret n) nod tar update tag define std 這一

題目大意:略 題目傳送門

四維偏序板子題

把插入操作和詢問操作抽象成$(x,y,z,t)$這樣的四元組

詢問操作拆分成八個詢問容斥

此外$x,y,z$可能很大,需要離散

直接處理四維偏序很困難,考慮降維

而$t$這一維有一個神奇的性質,任意兩個四元組的$t$互不相同,是最好處理的,所以盡量保證$t$這一維也出現在降維之後的$cdq$分治裏

外層把所有四元組按$x$排序,回溯按$t$排序

現在要處理左區間對右區間的影響了,把左區間裏的所有四元組打上$0$標記,右區間裏的所有四元組打上$1$標記

只有帶$0$標記的四元組能影響$1$標記的四元組

就這樣我們消掉了$x$這一維,只剩下$(y,z,t)$,再在當前區間跑三維偏序即可

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define N1 100010
  5 #define M1 400010
  6 #define ll long long
  7 #define dd double
  8 #define cll const long long 
  9 using namespace std;
 10 
 11 int gint()
 12 {
 13     int ret=0,fh=1;char c=getchar();
14 while(c<0||c>9){if(c==-)fh=-1;c=getchar();} 15 while(c>=0&&c<=9){ret=ret*10+c-0;c=getchar();} 16 return ret*fh; 17 } 18 struct BIT{ 19 int s[N1],ma; 20 void update(int x,int w){ for(int i=x;i<=ma;i+=(i&(-i))) s[i]+=w; } 21 int query(int
x){ int ans=0; for(int i=x;i>0;i-=(i&(-i))) ans+=s[i]; return ans; } 22 void clr(int x){ for(int i=x;i<=ma;i+=(i&(-i))) s[i]=0; } 23 }s; 24 int n,m,nn,T; 25 struct node{int x,y,z,t,p,tag,id;}a[M1],b[M1],tmp[M1]; 26 int xx[N1],nx,yy[N1],ny,zz[N1],nz,f[N1],que[M1],tl; 27 28 int cmp1(node s1,node s2) 29 { 30 if(s1.x!=s2.x) return s1.x<s2.x; 31 if(s1.y!=s2.y) return s1.y<s2.y; 32 if(s1.z!=s2.z) return s1.z<s2.z; 33 return s1.p*s1.p<s2.p*s2.p; 34 } 35 int cmp2(node s1,node s2) 36 { 37 if(s1.y!=s2.y) return s1.y<s2.y; 38 if(s1.z!=s2.z) return s1.z<s2.z; 39 if(s1.tag!=s2.tag) return s1.tag<s2.tag; 40 return s1.p*s1.p<s2.p*s2.p; 41 } 42 int cmp3(node s1,node s2){return s1.t<s2.t;} 43 int de; 44 45 void CDQ2(int L,int R) 46 { 47 if(R-L<=1) return; 48 int M=(L+R)>>1,i,j,cnt; 49 CDQ2(L,M); CDQ2(M,R); 50 for(i=L,j=M,cnt=0;i<M&&j<R;) 51 { 52 if(cmp2(b[i],b[j])){ 53 if(!b[i].tag&&!b[i].p){ s.update(b[i].z,1); que[++tl]=i; } 54 tmp[++cnt]=b[i]; i++; 55 }else{ 56 if(b[j].tag&&b[j].p){ f[b[j].id]+=b[j].p*s.query(b[j].z); } 57 tmp[++cnt]=b[j]; j++; 58 } 59 } 60 while(i<M){ tmp[++cnt]=b[i]; i++; } 61 while(j<R){ if(b[j].tag&&b[j].p) f[b[j].id]+=b[j].p*s.query(b[j].z); tmp[++cnt]=b[j]; j++; } 62 while(tl){ s.clr(b[que[tl--]].z); } 63 for(i=L;i<R;i++){ b[i]=tmp[i-L+1]; } 64 } 65 void CDQ1(int L,int R) 66 { 67 if(R-L<=1) return; 68 int M=(L+R)>>1,i,j,cnt; 69 CDQ1(L,M); CDQ1(M,R); 70 for(i=L,j=M,cnt=0;i<M&&j<R;) 71 { 72 if(a[i].t<a[j].t){ tmp[++cnt]=a[i]; tmp[cnt].tag=0; i++; } 73 else{ tmp[++cnt]=a[j]; tmp[cnt].tag=1; j++;} 74 } 75 while(i<M){ tmp[++cnt]=a[i]; tmp[cnt].tag=0; i++; } 76 while(j<R){ tmp[++cnt]=a[j]; tmp[cnt].tag=1; j++; } 77 for(nx=0,i=L;i<R;i++){ a[i]=b[i-L+1]=tmp[i-L+1]; } 78 sort(b+1,b+R-L+1,cmp3); 79 for(i=1;i<=R-L;i++){ b[i].t=i; } 80 CDQ2(1,R-L+1); 81 } 82 83 int main() 84 { 85 scanf("%d",&T); 86 while(T--){ 87 88 scanf("%d",&n); 89 int i,x,y,z,xa,xb,ya,yb,za,zb,p; 90 for(nn=0,nx=0,ny=0,nz=0,i=1;i<=n;i++) 91 { 92 p=gint(); f[i]=0; 93 if(p==1){ 94 x=gint(); y=gint(); z=gint(); f[i]=-1; 95 nn++; a[nn].x=x; a[nn].y=y; a[nn].z=z; a[nn].t=nn; a[nn].p=0; 96 xx[++nx]=x; yy[++ny]=y; zz[++nz]=z; 97 }else{ 98 xa=gint(); ya=gint(); za=gint(); xb=gint(); yb=gint(); zb=gint(); xa--; ya--; za--; 99 xx[++nx]=xa; xx[++nx]=xb; yy[++ny]=ya; yy[++ny]=yb; zz[++nz]=za; zz[++nz]=zb; 100 nn++; a[nn].x=xa; a[nn].y=ya; a[nn].z=za; a[nn].t=nn; a[nn].id=i; a[nn].p=-1; 101 nn++; a[nn].x=xb; a[nn].y=ya; a[nn].z=za; a[nn].t=nn; a[nn].id=i; a[nn].p=1; 102 nn++; a[nn].x=xa; a[nn].y=yb; a[nn].z=za; a[nn].t=nn; a[nn].id=i; a[nn].p=1; 103 nn++; a[nn].x=xa; a[nn].y=ya; a[nn].z=zb; a[nn].t=nn; a[nn].id=i; a[nn].p=1; 104 nn++; a[nn].x=xa; a[nn].y=yb; a[nn].z=zb; a[nn].t=nn; a[nn].id=i; a[nn].p=-1; 105 nn++; a[nn].x=xb; a[nn].y=ya; a[nn].z=zb; a[nn].t=nn; a[nn].id=i; a[nn].p=-1; 106 nn++; a[nn].x=xb; a[nn].y=yb; a[nn].z=za; a[nn].t=nn; a[nn].id=i; a[nn].p=-1; 107 nn++; a[nn].x=xb; a[nn].y=yb; a[nn].z=zb; a[nn].t=nn; a[nn].id=i; a[nn].p=1; 108 } 109 } 110 sort(xx+1,xx+nx+1); nx=unique(xx+1,xx+nx+1)-(xx+1); 111 sort(yy+1,yy+ny+1); ny=unique(yy+1,yy+ny+1)-(yy+1); 112 sort(zz+1,zz+nz+1); nz=unique(zz+1,zz+nz+1)-(zz+1); 113 for(i=1;i<=nn;i++) 114 { 115 a[i].x=lower_bound(xx+1,xx+nx+1,a[i].x)-xx; 116 a[i].y=lower_bound(yy+1,yy+ny+1,a[i].y)-yy; 117 a[i].z=lower_bound(zz+1,zz+nz+1,a[i].z)-zz; 118 } 119 sort(a+1,a+nn+1,cmp1); s.ma=nz; 120 CDQ1(1,nn+1); 121 for(i=1;i<=n;i++) 122 if(f[i]!=-1) printf("%d\n",f[i]); 123 124 } 125 return 0; 126 }

HDU 5126 stars (四維偏序+樹狀數組)