http://codeforces.com/gym/101350/problem/F
题意:
n只猴子坐在椅子上,有m次区间更新(笑话), 没听过这个笑话的猴子会掉到地上,原来听过这个笑话的猴子会做到椅子上。
问你最后有几只猴子坐在椅子上
数据输入就是线段树的经典输入。 由此联想到用线段树。
其次 猴子最后的状态其实只与他最后听到的那个笑话有关。
因此 我们可以把这个转化为区间染色问题既记录每只猴子最后听的笑话的颜色是啥。
然后,用类似于扫描线的方式。记录每个笑话的影响范围,左端点赋值为1 右端点赋值为-1. 排序之后一个一个点的扫描即可。
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<functional>
#include<cstring>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAX=1e5+10;
int add[MAX<<2];
void build(int l,int r,int rt)
{
add[rt]=-1;
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushdown(int rt)
{
if(add[rt]!=-1)
{
add[rt<<1]=add[rt<<1|1]=add[rt];
add[rt]=-1;
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l && R>=r)
{
add[rt]=c;
//printf("[%d,%d]\n",l,r);
return;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
}
int query(int p,int l,int r,int rt)
{
if(add[rt]!=-1)
return add[rt];
if(l==r)
return -1;
int m=(l+r)>>1;
if(p<=m) return query(p,lson);
else if(p>m) return query(p,rson);
}
class node
{
public:
int clor,h,v;
bool operator < (const node & b) const
{
return h<b.h;
}
};
int tot=0;
node nodes[MAX<<1];
void adds(int h,int id,int v)
{
nodes[tot].clor=id;
nodes[tot].h=h;
nodes[tot].v=v;
tot++;
}
int cloer[MAX];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(cloer,0,sizeof cloer);
int n,m;
tot=0;
scanf("%d %d",&n,&m);
build(1,n,1);
int x,l,k;
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&x,&l,&k);
int hi=min(x+k+1,n+1);
int low=max(x-k,1);
adds(low,l,1);
adds(hi,l,-1);
update(low,hi-1,l,1,n,1);
}
sort(nodes,nodes+tot);
int perh=1;
int index=0;
int ans=0;
//cout<<"tot"<<tot<<endl;
while(index<tot)
{
//cout<<index<<endl;
while(perh==nodes[index].h && index<tot)
{
//printf("nodes[%d]:%d %d %d\n",index,nodes[index].clor,nodes[index].h,nodes[index].v);
node &cnt=nodes[index];
cloer[cnt.clor]+=cnt.v;
index++;
}
for(int i=perh;i<nodes[index].h;i++)
{
int p=query(i,1,n,1);
//printf("query(%d,%d,%d,%d)\n",i,1,n,1);
if(p==-1) continue;
//printf("p:%d\n",p);
if(cloer[p]==1)
ans++;
}
perh=nodes[index].h;
}
cout<<n-ans<<endl;
}
}