线段树(成段更新),需要 离线离散化
成端更新,查询单点(只要涉及成端更新一定要打懒标记)
比赛时队友暴搞过了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; }