一个点跑到一个集合里,不止对自己有影响,也对这个集合中的所有东西有影响
一个一个改显然会炸
不妨打上修改标记,离散化后对每个点开个线段树,有东西加入时打上标记就好了
指针版不写内存回收MLE。。。麻麻我终于会写内存回收啦!
代码如下:
#include<algorithm>
#include<ctype.h>
#include<cstdio>
#include<queue>
#define pii pair<int,int>
#define N 30050
using namespace std;
inline int read(){
int x=0,f=1;char c;
do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
return x*f;
}
pii b[330050];
struct Data{
int v,x,y,k,maxw,maxv;
}a[N],q[300010];
struct Node{
Node *ls,*rs;
int cnt,maxx;
int flag1,flag2;
Node():ls(NULL),rs(NULL),cnt(0),maxx(0),flag1(0),flag2(0){}
inline void maintain(){
maxx=0;
if(ls) maxx=max(maxx,ls->maxx);
if(rs) maxx=max(maxx,rs->maxx);
return;
}
inline void Pushdown(){
if(ls) ls->flag1=max(ls->flag1,flag1),ls->flag2=max(ls->flag2,flag2);
if(rs) rs->flag1=max(rs->flag1,flag1),rs->flag2=max(rs->flag2,flag2);
flag1=flag2=0;
return;
}
}*root[330050];
queue<Node*>q1;
void Delete(Node* tmp){
if(tmp) q1.push(tmp);
return;
}
Node* New(){
if(!q1.empty()){
Node* tmp=q1.front();q1.pop();
tmp->ls=tmp->rs=NULL;
tmp->cnt=tmp->maxx=tmp->flag1=tmp->flag2=0;
return tmp;
}
return new Node;
}
int n,m,top;
void Insert(int L,int R,int x,int v,Node *&k){
if(!k) k=New();
k->cnt+=v;
if(L==R){
k->maxx=(~v)?a[x].v:0;
a[x].maxw=max(a[x].maxw,k->flag1);
a[x].maxv=max(a[x].maxv,k->flag2);
if(!k->cnt) Delete(k),k=NULL;
return;
}
k->Pushdown();
int mid=L+R>>1;
if(x<=mid) Insert(L,mid,x,v,k->ls);
else Insert(mid+1,R,x,v,k->rs);
k->maintain();
if(!k->cnt) Delete(k),k=NULL;
return;
}
int main(){
n=read();
for(int i=1;i<=n;i++){
a[i].v=read();
a[i].x=read();a[i].y=read();
b[++top]=pii(a[i].x,a[i].y);
}
m=read();
for(int i=1;i<=m;i++){
q[i].v=read();q[i].x=read();q[i].y=read();
b[++top]=pii(q[i].x,q[i].y);
}
sort(b+1,b+top+1);
top=unique(b+1,b+top+1)-b-1;
for(int i=1;i<=n;i++)
a[i].k=lower_bound(b+1,b+top+1,pii(a[i].x,a[i].y))-b;
for(int i=1;i<=m;i++)
q[i].k=lower_bound(b+1,b+top+1,pii(q[i].x,q[i].y))-b;
for(int i=1;i<=n;i++){
if(root[a[i].k]){
a[i].maxw=max(a[i].maxw,root[a[i].k]->maxx);
a[i].maxv=max(a[i].maxv,root[a[i].k]->cnt);
root[a[i].k]->flag1=max(root[a[i].k]->flag1,a[i].v);
root[a[i].k]->flag2=max(root[a[i].k]->flag2,root[a[i].k]->cnt);
}
Insert(1,n,i,1,root[a[i].k]);
}
for(int i=1;i<=m;i++){
Insert(1,n,q[i].v,-1,root[a[q[i].v].k]);
if(root[q[i].k]){
a[q[i].v].maxw=max(a[q[i].v].maxw,root[q[i].k]->maxx);
a[q[i].v].maxv=max(a[q[i].v].maxv,root[q[i].k]->cnt);
root[q[i].k]->flag1=max(root[q[i].k]->flag1,a[q[i].v].v);
root[q[i].k]->flag2=max(root[q[i].k]->flag2,root[q[i].k]->cnt);
}
Insert(1,n,q[i].v,1,root[a[q[i].v].k=q[i].k]);
}
for(int i=1;i<=n;i++) Insert(1,n,i,-1,root[a[i].k]);
for(int i=1;i<=n;i++)
printf("%lld\n",1ll*a[i].maxw*a[i].maxv);
return 0;
}