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吧
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }