三维偏序是一个很经典的东西啊。
//结果蒟蒻我居然是先写的四维的?
第一位排序当作限制,然后cdq分治+树状数组统计就好。写起来很快的啊。
题目:bzoj3262 陌上花开
1 #include<bits/stdc++.h> 2 #define N 100005 3 using namespace std; 4 int n,m,c[2*N],ans[N]; 5 struct Node{int a,b,c,s,ans;}a[N],p[N]; 6 inline bool cmp(Node x,Node y){ 7 if(x.a==y.a&&x.b==y.b)return x.c<y.c; 8 if(x.a==y.a)return x.b<y.b; 9 return x.a<y.a; 10 } 11 inline bool operator<(Node x,Node y){ 12 if(x.b==y.b)return x.c<y.c; 13 else return x.b<y.b; 14 } 15 inline int lowbit(int x){return x&(-x);} 16 inline void add(int x,int val){ 17 for(int i=x;i<=m;i+=lowbit(i))c[i]+=val; 18 } 19 inline int ask(int x){ 20 int ans=0; 21 for(int i=x;i;i-=lowbit(i))ans+=c[i]; 22 return ans; 23 } 24 void solve(int l,int r){ 25 if(l==r)return; 26 int mid=(l+r)>>1; 27 solve(l,mid);solve(mid+1,r); 28 sort(p+l,p+mid+1);sort(p+mid+1,p+r+1); 29 int i=l,j=mid+1; 30 while(j<=r){ 31 while(i<=mid&&p[i].b<=p[j].b){add(p[i].c,p[i].s);i++;} 32 p[j].ans+=ask(p[j].c);j++; 33 } 34 for(int j=l;j<i;j++)add(p[j].c,-p[j].s); 35 } 36 inline int read(){ 37 int f=1,x=0;char ch; 38 do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); 39 do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); 40 return f*x; 41 } 42 int main(){ 43 int nn=read();m=read(); 44 for(int i=1;i<=nn;i++)a[i].a=read(),a[i].b=read(),a[i].c=read(); 45 sort(a+1,a+nn+1,cmp);int cnt=0; 46 for(int i=1;i<=nn;i++){ 47 cnt++; 48 if(a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c){ 49 p[++n]=a[i];p[n].s=cnt;cnt=0; 50 } 51 } 52 solve(1,n); 53 for(int i=1;i<=n;i++)ans[p[i].ans+p[i].s-1]+=p[i].s; 54 for(int i=0;i<nn;i++)printf("%d ",ans[i]); 55 return 0; 56 }
然后是四维偏序。
四维偏序……额……蒟蒻我写的是K-D-Tree.关于KDtree可以在网上学习下,很niubi的一个东西。
我校的dalao都会三维KD-tree+神级剪枝,跑的速度快过香港新闻工作者。
我……写了个四维的KD-tree结果T成苟……
无奈,因为kd树不能转,就强行上了替罪羊那一套水过去了……
1 #include<bits/stdc++.h> 2 #define N 50010 3 #define inf 1000000009 4 #define lson (t1[o].l) 5 #define rson (t1[o].r) 6 using namespace std; 7 typedef long long ll; 8 int n,m,q[N],rt,dis,top=0;int tot=0,F; 9 inline int read(){ 10 int f=1,x=0;char ch; 11 do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); 12 do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); 13 return f*x; 14 }int ans=0; 15 struct Point{ 16 int d[4],maxv[4],minv[4],l,r,f,size,v,ma; 17 inline int& operator [] (int x){return d[x];} 18 inline int in(){for(int i=0;i<4;i++)d[i]=read();} 19 }t1[N],t2[N],it; 20 bool cmp(int a,int b){return t1[a][F]<t2[b][F];} 21 bool operator < (Point a,Point b){ 22 for(int i=0;i<=3;i++){ 23 if(a.d[i]<b.d[i])return 1; 24 if(a.d[i]>b.d[i])return 0; 25 } 26 return 0; 27 } 28 inline void pushup(int o){ 29 for(int i=0;i<=3;i++){ 30 t1[o].minv[i]=min(t1[o].d[i],min(t1[lson].minv[i],t1[rson].minv[i])); 31 t1[o].maxv[i]=max(t1[o].d[i],max(t1[lson].maxv[i],t1[rson].maxv[i])); 32 } 33 t1[o].ma=max(t1[o].v,max(t1[lson].ma,t1[rson].ma)); 34 t1[o].size=t1[lson].size+t1[rson].size+1; 35 } 36 int build(int l,int r,int f){ 37 int mid=(l+r)>>1;F=f; 38 nth_element(q+l,q+mid,q+r+1,cmp); 39 int o=q[mid];t1[o].f=f;lson=0;rson=0; 40 if(l<mid)lson=build(l,mid-1,(f+1)%4); 41 if(r>mid)rson=build(mid+1,r,(f+1)%4); 42 pushup(o);return o; 43 } 44 void dfs(int o){ 45 if(!o)return;q[++top]=o; 46 dfs(lson);dfs(rson); 47 } 48 void rebuild(int &o){ 49 top=0;dfs(o); 50 o=build(1,top,t1[o].f); 51 } 52 inline int newnode(int f){ 53 int o=++tot;t1[tot].f=f;t1[o]=it; 54 for(int i=0;i<=3;i++)t1[o].minv[i]=t1[o].maxv[i]=t1[o][i]; 55 t1[o].ma=t1[o].v;t1[o].size=1; 56 return o; 57 } 58 void ins(int &o,int f){ 59 if(!o){o=newnode(f);return;} 60 if(t1[o][f]<it[f]){ 61 ins(lson,(f+1)%4); 62 pushup(o); 63 if(t1[lson].size>t1[o].size*0.75)rebuild(o); 64 } 65 else{ 66 ins(rson,(f+1)%4); 67 pushup(o); 68 if(t1[rson].size>t1[o].size*0.75)rebuild(o); 69 } 70 } 71 inline int check(int o){ 72 if(!o)return 0;int _=0; 73 for(int i=0;i<=3;i++)if(t1[o].maxv[i]<=it.d[i])_++; 74 if(_==4)return _; 75 _=1; 76 for(int i=0;i<=3;i++)if(t1[o].minv[i]>it[i])_=0; 77 return _; 78 } 79 inline int calcdis(Point x,Point y){ 80 for(int i=0;i<=3;i++)if(x[i]>y[i])return 0; 81 return x.v; 82 } 83 void query(int o){ 84 ans=max(calcdis(t1[o],it),ans); 85 int dl=check(lson),dr=check(rson); 86 if(dl==4)ans=max(ans,t1[lson].ma); 87 else if(dl&&ans<t1[lson].ma)query(lson); 88 if(dr==4)ans=max(ans,t1[rson].ma); 89 else if(dr&&ans<t1[rson].ma)query(rson); 90 } 91 int main(){ 92 n=read(); 93 for(int i=0;i<=3;i++)t1[0].minv[i]=inf,t1[0].maxv[i]=-inf; 94 t1[0].ma=-inf; 95 for(int i=1;i<=n;i++){ 96 t2[i].in();t2[i].v=1; 97 } 98 sort(t2+1,t2+n+1); 99 int _=0; 100 for(int i=1;i<=n;i++){ 101 ans=0;it=t2[i]; 102 query(rt); 103 t2[i].v+=ans;it=t2[i]; 104 _=max(_,t2[i].v);ins(rt,0); 105 } 106 printf("%d ",_); 107 }