线段树(成段更新),需要 离线离散化
成端更新,查询单点(只要涉及成端更新一定要打懒标记)
比赛时队友暴搞过了ORZ
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int val[300100];
int a[100100],b[100100],tem[100100];
struct Tree{
int s;
int t;
int c;
int add;
}tree[1000010];
void build(int s,int t,int id){
tree[id].s=s;
tree[id].t=t;
tree[id].c=0;
tree[id].add=0;
if(s!=t){
int mid=(tree[id].s+tree[id].t)>>1;
build(s,mid,id*2);
build(mid+1,t,id*2+1);
}
}
void insert(int s,int t,int id){
if(tree[id].s==s && tree[id].t==t){
tree[id].c+=1;
tree[id].add+=1;
return ;
}
if(tree[id].add!=0){
tree[id*2].c+=tree[id].add;
tree[id*2+1].c+=tree[id].add;
tree[id*2].add+=tree[id].add;
tree[id*2+1].add+=tree[id].add;
tree[id].add=0;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(mid<s)
insert(s,t,id*2+1);
else if(mid>=t)
insert(s,t,id*2);
else{
insert(s,mid,id*2);
insert(mid+1,t,id*2+1);
}
tree[id].c=tree[id<<1].c+tree[id<<1|1].c;
}
int query(int s,int t,int id){
if(tree[id].s==s && tree[id].t==t)
return tree[id].c;
if(tree[id].add!=0){
tree[id*2].c+=tree[id].add;
tree[id*2+1].c+=tree[id].add;
tree[id*2].add+=tree[id].add;
tree[id*2+1].add+=tree[id].add;
tree[id].add=0;
}
int mid=(tree[id].s+tree[id].t)>>1;
if(mid<s)
return query(s,t,id*2+1);
else if(mid>=t)
return query(s,t,id*2);
else
return query(s,mid,id*2)+query(mid+1,t,id*2+1);
}
int main(){
int t,T,n,m,i,j,k,nn,temp;
scanf("%d",&T);
for(t=1;t<=T;t++){
printf("Case #%d:\n",t);
scanf("%d %d",&n,&m);
k=0;
for(i=1;i<=n;i++){
scanf("%d %d",&a[i],&b[i]);
val[k++]=a[i];
val[k++]=b[i];
}
for(i=1;i<=m;i++){
scanf("%d",&tem[i]);
val[k++]=tem[i];
}
sort(val,val+k);
nn=unique(val,val+k)-val;
build(1,nn,1);
for(i=1;i<=n;i++){
int p=lower_bound(val,val+nn,a[i])-val+1;
int q=lower_bound(val,val+nn,b[i])-val+1;
insert(p,q,1);
}
for(i=1;i<=m;i++){
temp=lower_bound(val,val+nn,tem[i])-val+1;
printf("%d\n",query(temp,temp,1));
}
}
return 0;
}