BZOJ2827 : 千山鸟飞绝

将坐标离散化后,对于每一个坐标建立一棵动态开节点的线段树,支持查询最大值、和,以及标记下放。

 

#include<cstdio>

#include<algorithm>

using namespace std;

typedef pair<int,int> P;

typedef long long ll;

const int N=30010,T=300010;

struct Bird{int w,x,y,loc,maxw,maxt;}A[N];

struct Ques{int v,x,y;}B[T];

struct Node{int l,r,taga,tagb,maxw,cnt;}seg[5000000];

P loc[N+T];

int n,m,i,tot;

inline void Max(int&a,int b){if(a<b)a=b;}

inline void read(int&a){

  char c;bool f=0;a=0;

  while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));

  if(c!='-')a=c-'0';else f=1;

  while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';

  if(f)a=-a;

}

inline int lower(P x){

  int l=1,r=n+m,mid,t;

  while(l<=r)if(loc[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;

  return t;

}

inline void add1(int x,int w,int t){

  if(!seg[x].cnt)return;

  Max(seg[x].taga,w),Max(seg[x].tagb,t);

}

void add(int x,int a,int b,int c,int d){

  seg[x].cnt+=d;

  if(a==b){

    seg[x].maxw=d==1?A[c].w:0;

    if(d==-1)Max(A[c].maxw,seg[x].taga),Max(A[c].maxt,seg[x].tagb);

    return;

  }

  if(seg[x].taga){

    add1(seg[x].l,seg[x].taga,seg[x].tagb),add1(seg[x].r,seg[x].taga,seg[x].tagb);

    seg[x].taga=seg[x].tagb=0;

  }

  int mid=(a+b)>>1;

  if(c<=mid){

    if(!seg[x].l)seg[x].l=++tot;

    add(seg[x].l,a,mid,c,d);

  }else{

    if(!seg[x].r)seg[x].r=++tot;

    add(seg[x].r,mid+1,b,c,d);

  }

  seg[x].maxw=max(seg[seg[x].l].maxw,seg[seg[x].r].maxw);

}

inline void fly(int x,int y){

  if(seg[y].cnt)Max(A[x].maxw,seg[y].maxw),Max(A[x].maxt,seg[y].cnt);

  add1(y,A[x].w,seg[y].cnt);

  add(A[x].loc=y,1,n,x,1);

}

int main(){

  read(n);

  for(i=1;i<=n;i++)read(A[i].w),read(A[i].x),read(A[i].y),loc[i]=P(A[i].x,A[i].y);

  read(m);

  for(i=1;i<=m;i++)read(B[i].v),read(B[i].x),read(B[i].y),loc[n+i]=P(B[i].x,B[i].y);

  sort(loc+1,loc+n+m+1);

  tot=n+m;

  for(i=1;i<=n;i++)fly(i,lower(P(A[i].x,A[i].y)));

  for(i=1;i<=m;i++)add(A[B[i].v].loc,1,n,B[i].v,-1),fly(B[i].v,lower(P(B[i].x,B[i].y)));

  for(i=1;i<=n;i++)add(A[i].loc,1,n,i,-1);

  for(i=1;i<=n;i++)printf("%lld\n",(long long)A[i].maxw*A[i].maxt);

  return 0;

}

  

 

你可能感兴趣的:(ZOJ)