bzoj2716 2716: [Violet 3]天使玩偶

2716: [Violet 3]天使玩偶

Time Limit: 80 Sec  Memory Limit: 128 MB
Submit: 2943  Solved: 1292
[Submit][Status][Discuss]

Description

Input

Output

同: 2648 ,需要插入的kd树。  
  1 #include<bits/stdc++.h>
  2 using namespace std;  
  3 int const maxn=1000000+100; 
  4 int const inf=1e9;    
  5 int n,m,cur,root;   
  6 struct P
  7 {
  8     int d[2],mx[2],mn[2],lch,rch;
  9     int& operator[](int x) {return d[x];}
 10     friend bool operator<(P x,P y) {return x[cur]<y[cur];}
 11     friend int dis(P x,P y) {return abs(x[0] -y[0])+abs(x[1]-y[1]);}
 12 }p[maxn]; 
 13 struct kdtree{
 14   P t[maxn],T;
 15   int ans;
 16   void update(int k){
 17         int l=t[k].lch;  
 18         int r=t[k].rch;   
 19         if(l){
 20             t[k].mn[0]=min(t[k].mn[0],t[l].mn[0]);  
 21             t[k].mx[0]=max(t[k].mx[0],t[l].mx[0]);  
 22             t[k].mn[1]=min(t[k].mn[1],t[l].mn[1]);  
 23             t[k].mx[1]=max(t[k].mx[1],t[l].mx[1]); 
 24         } 
 25         if(r){
 26             t[k].mn[0]=min(t[k].mn[0],t[r].mn[0]); 
 27             t[k].mx[0]=max(t[k].mx[0],t[r].mx[0]);  
 28             t[k].mn[1]=min(t[k].mn[1],t[r].mn[1]);  
 29             t[k].mx[1]=max(t[k].mx[1],t[r].mx[1]);  
 30         }  
 31     } 
 32   int build(int now,int l,int r)
 33   {
 34       cur=now;
 35       int mid=(l+r)/2;
 36       nth_element(p+l,p+mid,p+r+1);
 37       t[mid]=p[mid];
 38       for (int i=0;i<2;i++) t[mid].mn[i]=t[mid].mx[i]=t[mid][i];
 39       if (l<mid) t[mid].lch=build(now^1,l,mid-1);
 40       if (r>mid) t[mid].rch=build(now^1,mid+1,r);
 41       update(mid);
 42       return mid;
 43   }
 44   int getmn(P c){
 45         int ret=0;  
 46         ret+=max(0,c.mn[0]-T[0]);  
 47         ret+=max(0,T[0]-c.mx[0]);
 48         ret+=max(0,c.mn[1]-T[1]);  
 49         ret+=max(0,T[1]-c.mx[1]);  
 50         return ret;  
 51     }   
 52     void querymn(int k){
 53         ans=min(ans,dis(t[k],T)); 
 54         int l=t[k].lch;  
 55         int r=t[k].rch; 
 56         int vl=inf,vr=inf;  
 57         if(l) vl=getmn(t[l]);  
 58         if(r) vr=getmn(t[r]); 
 59         if(vl<vr){
 60             if(vl<ans) querymn(l);  
 61             if(vr<ans) querymn(r);  
 62         }else{
 63             if(vr<ans) querymn(r); 
 64             if(vl<ans) querymn(l); 
 65         } 
 66     }     
 67 
 68     void insert(int k,int now){
 69         if(T[now]>=t[k][now]){
 70             if(t[k].rch) insert(t[k].rch,now^1);  
 71             else {
 72                 t[k].rch=++n;  t[n]=T;  
 73                 //t[n].ch[0]=t[n].ch[1]=0;  
 74                 t[n].mx[0]=t[n].mn[0]=T[0];  
 75                 t[n].mx[1]=t[n].mn[1]=T[1]; 
 76             } 
 77         }else {
 78             if(t[k].lch) insert(t[k].lch,now^1);  
 79             else {
 80                 t[k].lch=++n; t[n]=T;  
 81             //    t[n].ch[0]=t[n].ch[1]=0; 
 82                 t[n].mx[0]=t[n].mn[0]=T[0]; 
 83                 t[n].mx[1]=t[n].mn[1]=T[1];   
 84             } 
 85         }
 86         update(k); 
 87     }     
 88     int query(int x,int y)
 89     {
 90         ans=inf;
 91         T[0]=x;T[1]=y;T.lch=0;T.rch=0;
 92         querymn(root);
 93         return ans;
 94     }
 95     void insert1(int x,int y)
 96     {
 97         T[0]=x;T[1]=y;T.lch=0;T.rch=0;insert(root,0);
 98     }
 99 }kd;    
100 int main(){   
101     scanf("%d%d",&n,&m);  
102     for(int i=1;i<=n;i++){
103         scanf("%d%d",&p[i][0],&p[i][1]);    
104     }  
105     root=kd.build(0,1,n); 
106     while (m--){
107         int t,x,y;  
108         scanf("%d%d%d",&t,&x,&y);  
109         if(t==1) kd.insert1(x,y);  
110         else printf("%d\n",kd.query(x,y)); 
111     } 
112     return 0; 
113 } 
View Code

 

本题还可以进行cdq分治。  

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 int const N=500000+10;  
 4 int const M=1000000+10;  
 5 int const inf=1e9;  
 6 struct node{
 7     int x,y,opt,id;  
 8 }q[N<<1],t[N<<1],tmp[N<<1];   
 9 int n,m,ans[N],len,c[M];   
10 void update(int x,int v){
11     for(int i=x;i<=len;i+=(i&-i))  
12         c[i]=max(c[i],v);  
13 }
14 void clear(int x){
15     for(int i=x;i<=len;i+=(i&-i))  
16         c[i]=0;  
17 }
18 int get(int x){
19     int s=0;  
20     for(int i=x;i;i-=(i&-i)) 
21         s=max(s,c[i]); 
22     return s? s:-inf;  
23 }    
24 void cdq(int l,int r){
25     if(l==r) return;   
26     int mid=(l+r)/2;  
27     cdq(l,mid);    
28     cdq(mid+1,r);   
29     int i=l,j=mid+1,k=l;  
30     while (i<=mid && j<=r){
31         if(t[i].x<=t[j].x){
32             if(t[i].opt==1)  
33                 update(t[i].y,t[i].x+t[i].y); 
34             tmp[k++]=t[i++]; 
35         }else {
36             if(t[j].opt==2)   
37             {
38                 ans[t[j].id]=min(ans[t[j].id],t[j].x+t[j].y-get(t[j].y));  
39             }
40             tmp[k++]=t[j++];  
41         }
42     }
43     while (i<=mid) {
44         if(t[i].opt==1)  update(t[i].y,t[i].x+t[i].y); 
45         tmp[k++]=t[i++];  
46     }
47     while (j<=r) {
48         if(t[j].opt==2)  ans[t[j].id]=min(ans[t[j].id],t[j].x+t[j].y-get(t[j].y)); 
49         tmp[k++]=t[j++];  
50     }
51     for(int i=l;i<=mid;i++)  
52         if(t[i].opt==1) clear(t[i].y);   
53     for(int i=l;i<=r;i++) t[i]=tmp[i];  
54 }
55 void solve(int a,int b){
56     for(int i=1;i<=n+m;i++){ 
57         t[i]=q[i];  
58         if(a) t[i].x=len-t[i].x;  
59         if(b) t[i].y=len-t[i].y;  
60     }
61     cdq(1,n+m); 
62 }
63 int main(){ 
64     scanf("%d%d",&n,&m);
65     for(int i=1;i<=n;i++){
66         q[i].opt=1;  
67         scanf("%d%d",&q[i].x,&q[i].y);   
68         q[i].x++; q[i].y++;   
69         len=max(q[i].x,len); 
70         len=max(q[i].y,len);  
71     } 
72     for(int i=n+1;i<=n+m;i++){
73         scanf("%d%d%d",&q[i].opt,&q[i].x,&q[i].y);  
74         q[i].id=i-n;  
75         q[i].x++;  
76         q[i].y++;  
77         len=max(q[i].x,len);  
78         len=max(q[i].y,len); 
79     }
80     for(int i=1;i<=m;i++) ans[i]=inf;  
81     len++;  
82     solve(0,0);  
83     solve(0,1);      
84     solve(1,0);  
85     solve(1,1);  
86     for(int i=n+1;i<=n+m;i++)  
87         if(q[i].opt==2)  printf("%d\n",ans[q[i].id]); 
88     return 0; 
89 }
View Code

 

posted @ 2019-07-04 10:58  zjxxcn  阅读(145)  评论(0编辑  收藏  举报