简单线段树,成段更新
#include <cstdio>
#define con 100100
using namespace std;
int em[con],l[con],r[con],n;
struct Tree{
int s;
int t;
int max;
int add;
}tree[270010];
int max(int a,int b){
return a>b?a:b;
}
void build(int s,int t,int id){
tree[id].s=s;tree[id].t=t;
tree[id].add=0;
if(s==t){
tree[id].max=em[s];
return;
}
int mid=(tree[id].s+tree[id].t)>>1;
build(s,mid,id*2);
build(mid+1,t,id*2+1);
tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
}
int query(int s,int t,int aim,int id){
if(s==t)
return s;
int mid=(tree[id].s+tree[id].t)>>1;
if(tree[id].add!=0){
tree[id*2].max+=tree[id].add;
tree[id*2].add+=tree[id].add;
tree[id*2+1].max+=tree[id].add;
tree[id*2+1].add+=tree[id].add;
tree[id].add=0;
}
if(tree[id*2+1].max>=aim)
return query(mid+1,t,aim,id*2+1);
else
return query(s,mid,aim,id*2);
}
void update1(int s,int id){
if(tree[id].s==s && tree[id].t==s){
tree[id].max=1;
return ;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(tree[id].add!=0){
tree[id*2].max+=tree[id].add;
tree[id*2].add+=tree[id].add;
tree[id*2+1].max+=tree[id].add;
tree[id*2+1].add+=tree[id].add;
tree[id].add=0;
}
if(mid<s)
update1(s,id*2+1);
else
update1(s,id*2);
tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
}
void update2(int s,int t,int aim,int id){
if(tree[id].s==s && tree[id].t==t){
tree[id].add+=aim;
tree[id].max+=aim;
return;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(tree[id].add!=0){
tree[id*2].max+=tree[id].add;
tree[id*2].add+=tree[id].add;
tree[id*2+1].max+=tree[id].add;
tree[id*2+1].add+=tree[id].add;
tree[id].add=0;
}
if(s>mid)
update2(s,t,aim,id*2+1);
else if(t<=mid)
update2(s,t,aim,id*2);
else{
update2(s,mid,aim,id*2);
update2(mid+1,t,aim,id*2+1);
}
tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++){
scanf("%d %d %d",&em[i],&l[i],&r[i]);
}
build(1,n,1);
int m,tem;
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%d",&tem);
if(tem>tree[1].max)
update2(1,n,1,1);
else{
int per=query(1,n,tem,1);
update1(per,1);
update2(l[per],r[per],1,1);
}
}
printf("%d\n",tree[1].max);
}
}