很明显的线段树, 可是(1 <= Si <= Ti <= 10^9)啊!!这是什么概念,一定要离散话的!!可数据弱的都没离散就过了,要是有一组1,10^9,那没离散话的不就全挂了,数据好弱啊
先吧左右点离散话,然后每条边的s为这条边的染色次数,querry是就吧沿路边加载一起
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define N 100005 struct node{ int l,r,s; }a[N*6]; int pa[N*2],cou,sum,cou1,tt; int aa[N],bb[N],qq[N]; void build(int i,int left,int right){ a[i].l=left; a[i].r=right; a[i].s=0; if(a[i].l==a[i].r) return ; int mid=(left+right)>>1; build(i*2,left,mid); build(i*2+1,mid+1,right); } void insert(int i,int left,int right){ if(a[i].l==left&&a[i].r==right){ a[i].s++; return ; } int mid=(a[i].l+a[i].r)>>1; if(left>mid) insert(i*2+1,left,right); else if(right<=mid) insert(i*2,left,right); else{ insert(i*2,left,mid); insert(i*2+1,mid+1,right); } } int querry(int i,int x){ sum+=a[i].s; if(x==a[i].l&&x==a[i].r){ return sum; } int mid=(a[i].l+a[i].r)>>1; if(x>mid) { querry(i*2+1,x); } else if(x<=mid) { querry(i*2,x); } } int find(int x){ int l=1,r=tt-1; while(r>=l){ int mid=(l+r)>>1; if(x>pa[mid]) l=mid+1; if(x<pa[mid]) r=mid-1; if(x==pa[mid]) return mid; } return 0; } int main(){ // freopen("in.txt","r",stdin); int t,n,m,x,y,z,p=1; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); cou=1; for(int i=0;i<n;i++){ scanf("%d%d",&x,&y); aa[i]=x; bb[i]=y; pa[cou++]=x; pa[cou++]=y; } for(int i=0;i<m;i++){ scanf("%d",&qq[i]); pa[cou++]=qq[i]; } printf("Case #%d:\n",p++); sort(pa+1,pa+cou); int cou1=1; pa[cou]=-1; for(int i=1;i<cou;i++){ if(pa[i]!=pa[i+1]) pa[cou1++]=pa[i]; else continue; } build(1,0,cou1-1); tt=cou1; for(int i=0;i<n;i++){ int ta=find(aa[i]); int tb=find(bb[i]); insert(1,ta,tb); } for(int i=0;i<m;i++){ int z=find(qq[i]); sum=0; printf("%d\n",querry(1,z)); } } return 0; }