【偏序问题】三维偏序,四维偏序

三维偏序是一个很经典的东西啊。

//结果蒟蒻我居然是先写的四维的?

第一位排序当作限制,然后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\n",ans[i]);
55     return 0;
56 }
View Code

然后是四维偏序。

四维偏序……额……蒟蒻我写的是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\n",_);
107 }
kd-tree

 

posted @ 2017-05-10 21:53  zcysky  阅读(509)  评论(0编辑  收藏  举报