#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/45721413");
}
首先先把坐标离散化一下,
然后对于每个坐标点我们建一棵平衡树,每次插入操作后给整颗平衡树下传一下需求的两个标记。
splay有的人(比如我)习惯每棵都先建-inf、inf两个节点以便于查找前驱后继。然后这道题的数据是爆0x3f3f3f3f的……呵呵,怪不得我跑了千组极限数据都没挂,然后vfk的数据我直接爆零……(我的点权值随机的[1,10086])
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 35000
#define M 700000
#define ls son[x][0]
#define rs son[x][1]
#define end(i) n+(i<<1)
#define is(x) (son[fa[x]][1]==x)
#define inf 0x7fffffff
using namespace std;
int ad[M],ap[M]; // 团结值、士气值
struct DATA
{
int v,f,k; // 第v只鸟于时刻f飞到k处。
long long x,y;
void read(int _f){f=_f;scanf("%d%lld%lld",&v,&x,&y);}
}gank[M];
bool cmpf(const DATA &A,const DATA &B){return A.f<B.f;}
bool cmpxy(const DATA &A,const DATA &B){return A.x==B.x?A.y<B.y:A.x<B.x;}
int n,m,cnt;
struct SPT
{
int root[M],belong[M];
int son[M][2],fa[M],kda[M]; // 威武值
int AD[M],AP[M],num[M];
void pushdown(int x)
{
ad[x]=max(ad[x],AD[x]);
ap[x]=max(ap[x],AP[x]);
AD[ls]=max(AD[ls],AD[x]);
AD[rs]=max(AD[rs],AD[x]);
AP[ls]=max(AP[ls],AP[x]);
AP[rs]=max(AP[rs],AP[x]);
AD[x]=AP[x]=0;
}
void link(int x,int y,int d){son[y][d]=x,fa[x]=y;}
void rotate(int x)
{
int y,z,i=is(x),t;
y=fa[x],z=fa[y],t=son[x][!i];
pushdown(y),pushdown(x);
link(x,z,is(y)),link(y,x,!i),link(t,y,i);
son[0][0]=son[0][1]=fa[0]=0;
}
void splay(int rt,int x,int d=0)
{
int y,z;
while(fa[x]!=d)
{
y=fa[x],z=fa[y];
if(z==d)rotate(x);
else rotate(is(x)==is(y)?y:x),rotate(x);
}
if(!d)root[rt]=x;
}
int pred(int rt,int x)
{
splay(rt,x);
for(x=ls;rs;x=rs);
return x;
}
void insert(int rt,int v)
{
belong[v]=rt;
int x=root[rt],pre,pr;pushdown(x);
while(son[x][kda[x]<kda[v]])
pushdown(x=son[x][kda[x]<kda[v]]);
link(v,x,kda[x]<kda[v]),num[rt]++;
splay(rt,v);
pre=pred(rt,end(rt));
pr=pred(rt,pre);
if(pre<=n)
{
pushdown(pre);
AD[pre]=num[rt]-1;
ap[pre]=max(ap[pre],kda[pr]);
int lss=son[pre][0],rss=son[pre][1];
AP[lss]=max(AP[lss],kda[pre]);
AP[rss]=max(AP[rss],kda[pre]);
}
}
void remove(int rt,int x)
{
int pre=pred(rt,x);
splay(rt,pre),splay(rt,x,pre);
pushdown(pre),pushdown(x);
link(rs,pre,1),num[rt]--;
ls=rs=fa[x]=0;
}
void init(int m)
{
int a,b;
for(int i=1;i<=m;i++)
{
b=end(i),a=b-1;
root[i]=a,kda[a]=-inf;
link(b,a,1),kda[b]=inf;
}
for(int i=1;i<=n;i++)insert(gank[i].k,gank[i].v);
}
void work(int i)
{
remove(belong[gank[i].v],gank[i].v);
insert(gank[i].k,gank[i].v);
}
}spt;
int main()
{
int i,j,k;
int a,b,c;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
gank[i].read(0);
spt.kda[i]=gank[i].v;
gank[i].v=i;
}
scanf("%d",&m);
for(i=1;i<=m;i++)gank[i+n].read(i);
sort(gank+1,gank+n+m+1,cmpxy);
gank[0].x=gank[1].x^1;
for(i=1;i<=n+m;i++)
{
if(gank[i].x!=gank[i-1].x||gank[i].y!=gank[i-1].y)cnt++;
gank[i].k=cnt;
}
sort(gank+1,gank+n+m+1,cmpf);
spt.init(cnt);
for(i=n+1;i<=n+m;i++)
spt.work(i);
for(i=1;i<=n;i++)spt.remove(spt.belong[i],i);
for(i=1;i<=n;i++)printf("%lld\n",(long long)ad[i]*ap[i]);
return 0;
}
原文地址:http://blog.csdn.net/vmurder/article/details/45721413