Crowd HDU - 4456 曼哈顿距离转切比雪夫距离的坐标变换与二维坐标离散化

通过坐标变换x'=x-y+n和y'=x+y,开大两倍空间就可以用一个两倍大的二维矩阵中

从[x'-a,y'-a]到[x'+a,y'+a]这个子矩阵表示原图中到(x,y)曼哈顿距离小于等于a的菱形区域啦

二维的离散化就是把(x,y)映射到x*n+y这个一维数列上

这题极限空间应该是log(2n)*log(2n)*m吧。。这是2e7左右了呀,不知道4e6怎么过的?可能离散不出那么多严格的logN吧

 1 //#include<bits/stdc++.h>  
 2 //#pragma comment(linker, "/STACK:1024000000,1024000000")   
 3 #include<stdio.h>  
 4 #include<algorithm>  
 5 #include<queue>  
 6 #include<string.h>  
 7 #include<iostream>  
 8 #include<math.h>                    
 9 #include<stack>
10 #include<set>  
11 #include<map>  
12 #include<vector>  
13 #include<iomanip> 
14 #include<bitset>
15 using namespace std;         //
16 
17 #define ll long long  
18 #define ull unsigned long long
19 #define pb push_back  
20 #define FOR(a) for(int i=1;i<=a;i++) 
21 #define sqr(a) (a)*(a)
22 #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
23 ll qp(ll a,ll b,ll mod){
24     ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
25 }
26 struct DOT{int x;int y;};
27 inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
28 void ex(){puts("No");exit(0);}
29 const int dx[4]={0,0,-1,1};
30 const int dy[4]={1,-1,0,0};
31 const int inf=0x3f3f3f3f; 
32 const ll Linf=0x3f3f3f3f3f3f3f3fLL;
33 const ll Mod=1e18+7;
34 const double eps=1e-6;
35 const double pi=acos(-1.0);
36 
37 
38 
39 inline int lowbit(int x){return x&-x;}
40 
41 const int maxn=8e4+33;
42 
43 int op[maxn],posx[maxn],posy[maxn];
44 int v[maxn],h[4000050],tree[4000050],n,m,N,cnt;
45 
46 void add(int x,int y,int z){
47     for(int i=x;i<=N;i+=lowbit(i)){
48         for(int j=y;j<=N;j+=lowbit(j)){
49             int pos=lower_bound(h,h+cnt,i*N+j)-h;
50             tree[pos]+=z;
51         }
52     }
53 }
54 int ask(int x,int y){
55     int ans=0;
56     for(int i=x;i>0;i-=lowbit(i)){
57         for(int j=y;j>0;j-=lowbit(j)){
58             int pos=lower_bound(h,h+cnt,i*N+j)-h;
59             if(h[pos]==i*N+j)ans+=tree[pos];
60         }
61     }
62     return ans;
63 }
64 
65 int main(){
66     while(scanf("%d",&n)&&n){
67         memset(tree,0,sizeof tree);
68         int x,y;
69         N=2*n;
70         cnt=0;
71         scanf("%d",&m);
72         for(int i=1;i<=m;i++){
73             scanf("%d%d%d%d",&op[i],&x,&y,&v[i]);
74             int xx=x-y+n;int yy=x+y;
75             posx[i]=xx;
76             posy[i]=yy;
77             if(op[i]==1){
78                 for(int j=xx;j<=N;j+=lowbit(j)){
79                     for(int k=yy;k<=N;k+=lowbit(k)){
80                         h[cnt++]=j*N+k;
81                     }
82                 }
83             }
84         }
85         sort(h,h+cnt);
86         for(int i=1;i<=m;i++){
87             if(op[i]==1)add(posx[i],posy[i],v[i]);
88             else{
89                 int X1=max(1,posx[i]-v[i]),Y1=max(1,posy[i]-v[i]);
90                 int X2=min(N,posx[i]+v[i]),Y2=min(N,posy[i]+v[i]);
91                 printf("%d\n",ask(X2,Y2)+ask(X1-1,Y1-1)
92                         -ask(X2,Y1-1)-ask(X1-1,Y2)
93                         );
94             }
95         }
96     }
97 }
View Code

 

posted @ 2018-03-30 20:51  Drenight  阅读(253)  评论(0编辑  收藏  举报