题意:有一个10000000长的墙,在墙上贴n张海报,每张海报长度相等,宽度li到ri,问贴完以后能看到几张不同的海报
思路:简单的线段树染色问题,离散化给的宽度,注意要把[li,ri]离散化为[li,ri+1),避免出错,给个样例体会一下
3
5 6
4 5
6 7
答案应该是3
题很简单,但是过题过到废,题目给的n是10000,我本来maxn=10010,然后nd数组和v数组都开得maxn,然后tree和lazy开的maxn<<3,结果疯狂re,就把nd和v都开了maxn<<2,tree和lazy开了maxn*10,结果wa了,搞了很多样例都过了,最后看了讨论区,然后把maxn开成了100010,就过了!!!!!!!!!!啊,我猜这题n值应该是1e5
//#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
vector<int>vc;
struct node{
int l,r;
}nd[maxn<<2];
int v[maxn<<2],ans;
int tree[maxn*10],lazy[maxn*10];
int getid(int x){
return lower_bound(vc.begin(),vc.end(),x)-vc.begin()+1;
}
#define rl (rt<<1)
#define rr (rt<<1|1)
void down(int rt){
if(lazy[rt]){
lazy[rl]=lazy[rt];
lazy[rr]=lazy[rt];
tree[rl]=lazy[rt];
tree[rr]=lazy[rt];
lazy[rt]=0;
}
}
void up(int rt){
if(tree[rl]==tree[rr]) tree[rt]=tree[rl];
else if(!tree[rl] || !tree[rr]) tree[rt]=tree[rl]+tree[rr];
else tree[rt]=-1;
}
void update(int x,int y,int z,int l,int r,int rt){
if(x<=l && r<=y){
tree[rt]=z;
lazy[rt]=z;
return;
}
down(rt);
int mid=(l+r)>>1;
if(x<=mid) update(x,y,z,l,mid,rl);
if(y>mid) update(x,y,z,mid+1,r,rr);
up(rt);
}
void query(int l,int r,int rt){
if(tree[rt]>0){
if(!v[tree[rt]]) ans++;
v[tree[rt]]++;
return;
}
if(l==r) return;
if(!tree[rt]) return;
down(rt);
int mid=(l+r)>>1;
query(l,mid,rl);
query(mid+1,r,rr);
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
memset(tree,0,sizeof(tree));
memset(v,0,sizeof(v));
memset(lazy,0,sizeof(lazy));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&nd[i].l,&nd[i].r);
nd[i].r++;
vc.push_back(nd[i].l);
vc.push_back(nd[i].r);
}
sort(vc.begin(),vc.end()),vc.erase(unique(vc.begin(),vc.end()),vc.end());
int l=vc.size();
for(int i=1;i<=n;i++) update(getid(nd[i].l),getid(nd[i].r)-1,i,1,l,1);
ans=0;
query(1,l,1);
printf("%d\n",ans);
}
return 0;
}