poj~2528~離散化線段樹
阿新 • • 發佈:2019-02-07
資料範圍太大,先離散化,離散化注意不相鄰的點不能離散成連續的,不然會有錯誤,然後用線段樹記錄點上的lazy值,最後統計就ok了。
ACcode:
#include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; const int size=11111; struct Edge { int le,ri; }edge[size]; int n; int *p[size<<1]; int lazy[size<<4]; bool hash[size]; bool cmp1(int *aa,int *bb) { return *aa<*bb; } void pushdown(int rt) { if (lazy[rt]) { lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; lazy[rt]=0; } } void update(int rt,int l,int r,int L,int R,int v) { if (L<=l&&r<=R) { lazy[rt]=v; return ; } pushdown(rt); int mid=(l+r)>>1; if (L<=mid) update(rt<<1,l,mid,L,R,v); if (R>mid) update(rt<<1|1,mid+1,r,L,R,v); } int query(int rt,int l,int r) { if (lazy[rt]) { if (hash[lazy[rt]]) { hash[lazy[rt]]=false; return 1; } else return 0; } if (l==r) return 0; int mid=(l+r)>>1,ans=0; ans+=query(rt<<1,l,mid); ans+=query(rt<<1|1,mid+1,r); return ans; } int main() { int cas,i,j,k,num,pre,cnt; for (scanf("%d",&cas);cas--;) { scanf("%d",&n); for (num=i=0;i<n;i++) { scanf("%d %d",&edge[i].le,&edge[i].ri); p[num++]=&edge[i].le; p[num++]=&edge[i].ri; } sort(p,p+num,cmp1); pre=*p[0], *p[0]=1; memset(lazy,0,sizeof(lazy)); memset(hash,true,sizeof(hash)); for (k=1,i=1;i<num;i++) { if (*p[i]==pre+1) k++; else if (*p[i]>(pre+1)) k+=2; pre=*p[i]; *p[i]=k; } // for (i=0;i<n;i++) printf("e[%d]: %d %d\n",i,edge[i].le,edge[i].ri); for (i=0;i<n;i++) update(1,1,k,edge[i].le,edge[i].ri,i+1); cnt=query(1,1,k); printf("%d\n",cnt); } return 0; }