poj 3263 區間覆蓋統計
阿新 • • 發佈:2019-01-09
線段樹求區間覆蓋,注意去重複區間。
#include<stdio.h> #include<iostream> #include<algorithm> #include<set> #include<string.h> using namespace std; const int maxn=10005; typedef pair<int, int> PII; set <PII> C; int cnt[maxn],N,I,H,R; struct Tree { int l,r,cov; }t[maxn<<2]; #define mid ((t[p].l+t[p].r)>>1) #define ls (p<<1) #define rs ((ls)+1) void build(int p,int l,int r) { t[p].l=l;t[p].r=r;t[p].cov=0; if(l==r) return ; build(ls,l,mid); build(rs,mid+1,r); } void modify(int p,int l,int r) { if(l>r) return ; if(t[p].l==l && t[p].r==r) { t[p].cov++; return; } if(r<=mid) modify(ls,l,r); else if(l>=mid+1) modify(rs,l,r); else { modify(ls,l,mid); modify(rs,mid+1,r); } } void query(int p) { if(t[p].l==t[p].r) { cnt[t[p].l]=t[p].cov; return ; } if(t[p].cov) { t[ls].cov+=t[p].cov; t[rs].cov+=t[p].cov; } query(ls); query(rs); } int main() { // freopen("test.txt","r",stdin); scanf("%d%d%d%d",&N,&I,&H,&R); build(1,1,N); memset(cnt,0,sizeof(cnt)); for(int i=0;i<R;i++) { int a,b; scanf("%d%d",&a,&b); if(a>b) swap(a,b); if(!C.count(PII(a,b))) { C.insert(PII(a,b)); modify(1,a+1,b-1); } } query(1); for(int i=1;i<=N;i++) printf("%d\n",H-cnt[i]); return 0; }