2648这题卡常数.加了inline.开了内存池.卡时过掉了.
/* I will wait for you */
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int maxn=400010;
const int maxm=210;
const int maxs=26;
const int INF=1<<28;
const int P=1000000007;
const double error=1e-9;
struct node
{
int x,y,mix,max,miy,may;
node* son[2];
}su[maxn];
int cnt=0,ans;
inline void init(node* &a,int x,int y)
{
a->x=a->mix=a->max=x;
a->y=a->miy=a->may=y;
a->son[0]=a->son[1]=0;
}
inline void maintain(node* o)
{
o->mix=o->max=o->x;
o->miy=o->may=o->y;
for(int i=0;i<2;i++) if(o->son[i])
{
o->mix=min(o->mix,o->son[i]->mix);
o->max=max(o->max,o->son[i]->max);
o->miy=min(o->miy,o->son[i]->miy);
o->may=max(o->may,o->son[i]->may);
}
}
inline void insert(node* &o,int x,int y,int d)
{
if(!o) o=&su[cnt++],init(o,x,y);
else
{
if(d==0) insert(o->son[x>o->x],x,y,d^1);
if(d==1) insert(o->son[y>o->y],x,y,d^1);
maintain(o);
}
}
inline int dis(node* o,int x,int y)
{
int ans=0;
if(x<o->mix) ans+=o->mix-x;
if(x>o->max) ans+=x-o->max;
if(y<o->miy) ans+=o->miy-y;
if(y>o->may) ans+=y-o->may;
return ans;
}
inline int find(node* o,int x,int y)
{
int dn=abs(x-o->x)+abs(y-o->y);
ans=min(ans,dn);
int dl=o->son[0]?dis(o->son[0],x,y):INF;
int dr=o->son[1]?dis(o->son[1],x,y):INF;
if(dl<=dr)
{
if(dl<ans) find(o->son[0],x,y);
if(dr<ans) find(o->son[1],x,y);
}
if(dr<dl)
{
if(dr<ans) find(o->son[1],x,y);
if(dl<ans) find(o->son[0],x,y);
}
}
int main()
{
int n,m;node* root=0;
scanf("%d%d",&n,&m);
for(int i=0,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(root,x,y,0);
while(m--)
{
int t,x,y;scanf("%d%d%d",&t,&x,&y);
if(t==1) insert(root,x,y,0);
if(t==2) ans=INF,find(root,x,y),printf("%d\n",ans);
}
return 0;
}
发现最开始给定的节点不用逐一插入.可以直接建树.
/* I will wait for you */
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int maxn=2000010;
const int maxm=210;
const int maxs=26;
const int INF=1<<28;
const int P=1000000007;
const double error=1e-9;
struct node
{
int x,y,mix,max,miy,may;
node* son[2];
}su[maxn];
struct point{ int x,y; }e[maxn];
bool cmpx(point a,point b)
{
return a.x<b.x;
}
bool cmpy(point a,point b)
{
return a.y<b.y;
}
int cnt=0,ans;
inline void init(node* &a,int x,int y)
{
a->x=a->mix=a->max=x;
a->y=a->miy=a->may=y;
a->son[0]=a->son[1]=0;
}
inline void maintain(node* o)
{
o->mix=o->max=o->x;
o->miy=o->may=o->y;
for(int i=0;i<2;i++) if(o->son[i])
{
o->mix=min(o->mix,o->son[i]->mix);
o->max=max(o->max,o->son[i]->max);
o->miy=min(o->miy,o->son[i]->miy);
o->may=max(o->may,o->son[i]->may);
}
}
inline node* build(int l,int r,int d)
{
int mid=(l+r)>>1;
if(d==0) nth_element(e+l,e+mid,e+r+1,cmpx);
if(d==1) nth_element(e+l,e+mid,e+r+1,cmpy);
node* o=&su[cnt++];init(o,e[mid].x,e[mid].y);
if(l!=mid) o->son[0]=build(l,mid-1,d^1);
if(r!=mid) o->son[1]=build(mid+1,r,d^1);
maintain(o);return o;
}
inline void insert(node* &o,int x,int y,int d)
{
if(!o) o=&su[cnt++],init(o,x,y);
else
{
if(d==0) insert(o->son[x>o->x],x,y,d^1);
if(d==1) insert(o->son[y>o->y],x,y,d^1);
maintain(o);
}
}
inline int dis(node* o,int x,int y)
{
int ans=0;
if(x<o->mix) ans+=o->mix-x;
if(x>o->max) ans+=x-o->max;
if(y<o->miy) ans+=o->miy-y;
if(y>o->may) ans+=y-o->may;
return ans;
}
inline int find(node* o,int x,int y)
{
int dn=abs(x-o->x)+abs(y-o->y);
ans=min(ans,dn);
int dl=o->son[0]?dis(o->son[0],x,y):INF;
int dr=o->son[1]?dis(o->son[1],x,y):INF;
if(dl<=dr)
{
if(dl<ans) find(o->son[0],x,y);
if(dr<ans) find(o->son[1],x,y);
}
if(dr<dl)
{
if(dr<ans) find(o->son[1],x,y);
if(dl<ans) find(o->son[0],x,y);
}
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
for(int i=1,x,y;i<=n;i++) scanf("%d%d",&e[i].x,&e[i].y);
node* root=build(1,n,0);
while(m--)
{
int t,x,y;scanf("%d%d%d",&t,&x,&y);
if(t==1) insert(root,x,y,0);
if(t==2) ans=INF,find(root,x,y),printf("%d\n",ans);
}
<span style="white-space:pre"> </span>return 0;
}