前置知识
CDQ 分治 | 权值树状数组及应用 | 曼哈顿距离与切比雪夫距离的相互转化
解法
增加一维为时间戳,那么操作 \(1\) 等价于单点加。
曼哈顿距离直接跑 CDQ 分治,貌似不太可做,考虑转化为切比雪夫距离。
- 原曼哈顿坐标系中的点 \((x_{1},y_{1}),(x_{2},y_{2})\) 间的距离等价于切比雪夫坐标系中的 \((x_{1}+y_{1},x_{1}-y_{1}),(x_{2}+y_{2},x_{2}-y_{2})\)。
- 即 \(|x_{1}-x_{2}|+|y_{1}-y_{2}|=\max(|x_{1}+y_{1}-x_{2}-y_{2}|,|x_{1}-y_{1}-x_{2}+y_{2}|)\),将左边的绝对值展开并进行归纳即可证明。
题意转化为求以 \((x,a_{x})\) 为中心的以 \(2k\) 为边长的正方形内点的个数,同 luogu P4390 [BalkanOI2007] Mokia 摩基亚 二维数点维护即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
struct node
{
int t,x,y,pd,val,id;
bool operator < (const node &another) const
{
return (x==another.x)?((y==another.y)?(pd>another.pd):(y<another.y)):(x<another.x);
}
}a[500010],tmp[500010];
int ans[500010],y[500010],b[500010],cnt=0,q_cnt=0;
void add(int t,int x,int y,int pd,int val,int id)
{
cnt++;
a[cnt].t=t;
a[cnt].x=x;
a[cnt].y=y;
a[cnt].pd=pd;
a[cnt].val=val;
a[cnt].id=id;
}
struct BIT
{
int c[500010];
int lowbit(int x)
{
return (x&(-x));
}
void add(int n,int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
{
c[i]+=val;
}
}
int getsum(int x)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i))
{
ans+=c[i];
}
return ans;
}
}T;
void cdq(int l,int r,int k)
{
if(l==r)
{
return;
}
int mid=(l+r)/2,x,y;
cdq(l,mid,k);
cdq(mid+1,r,k);
sort(a+l,a+mid+1);
sort(a+mid+1,a+r+1);
for(x=l,y=mid+1;y<=r;y++)
{
for(;a[x].x<=a[y].x&&x<=mid;x++)
{
T.add(k,a[x].y,a[x].pd);
}
ans[a[y].id]+=a[y].val*T.getsum(a[y].y);
}
x--;
for(int i=l;i<=x;i++)
{
T.add(k,a[i].y,-a[i].pd);
}
}
int main()
{
int n,m,x,k,i;
string pd;
cin>>n>>m;
for(i=1;i<=n;i++)
{
cin>>y[i];
add(0,i+y[i],i-y[i],1,0,0);
b[0]++;
b[b[0]]=i-y[i];
}
for(i=1;i<=m;i++)
{
cin>>pd;
if(pd=="Modify")
{
cin>>x;
cin>>y[x];
add(i,x+y[x],x-y[x],1,0,0);
b[0]++;
b[b[0]]=x-y[x];
}
else
{
cin>>x>>k;
q_cnt++;
add(i,x+y[x]+k,x-y[x]+k,0,1,q_cnt);
b[0]++;
b[b[0]]=x-y[x]+k;
add(i,x+y[x]-k-1,x-y[x]+k,0,-1,q_cnt);
b[0]++;
b[b[0]]=x-y[x]+k;
add(i,x+y[x]+k,x-y[x]-k-1,0,-1,q_cnt);
b[0]++;
b[b[0]]=x-y[x]-k-1;
add(i,x+y[x]-k-1,x-y[x]-k-1,0,1,q_cnt);
b[0]++;
b[b[0]]=x-y[x]-k-1;
}
}
sort(b+1,b+1+b[0]);
b[0]=unique(b+1,b+1+b[0])-(b+1);
for(i=1;i<=cnt;i++)
{
a[i].y=lower_bound(b+1,b+1+b[0],a[i].y)-b;
}
cdq(1,cnt,b[0]);
for(i=1;i<=q_cnt;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
标签:cnt,++,题解,mid,P10633,int,add,pd,BZOJ2989
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18361045