2017暑假集训 div1 线段树(1)

来源:互联网 发布:linux fm驱动 编辑:程序博客网 时间:2024/06/06 00:18

POJ 2528

题意:铺海报,问最后能看到几种海报

做法:原来做过的题,也写过博客。然而离散化还是不太会啊,大神的的离散化太巧妙了!

for(int i=1;i<=m;++i)        {            scanf("%d%d",&x[i],&y[i]);            hash[++cnt]=x[i];            hash[++cnt]=y[i];        }        sort(hash+1,hash+1+cnt);        int num=1;        for(int i= 2;i<=cnt;++i)        {            if(hash[num]!=hash[i]) hash[++num]=hash[i];        }        for(int i=num; i>=0;--i)        {            if(hash[i]-hash[i-1]>1) hash[++num]=hash[i]-1;        }        sort(hash+1,hash+1+num);


二分:

int bsearch(int l,int r,int x){    int m;    while(l<=r)    {        int m=(l+r)>>1;        if(hash[m]==x) return m;        else if(hash[m]>x) r=m-1;        else l=m+1;    }    return l;}

ZOJ 1610

题意:每次将[L,R]端点覆盖,问最后每个颜色有多少个连续的子段(如果没有则不输出)

做法:模拟覆盖,最后统计的时候,每次记录一下前一个点的颜色即可

注意:这里的L,R都是端点,其实覆盖的是[L+1,R]这个大区间,其中每个节点表示长度为1的小区间

还有一个坑点:L,R范围不确定,直接上8000把

#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#define lson rt<<1,begin,mid#define rson rt<<1|1,mid+1,endusing namespace std;const int maxn=8000;int tree[maxn*4 +5];int ans[maxn*4 +5];int pre;void pushdown(int rt){    if(tree[rt]!=-1)    {        tree[rt<<1] = tree[rt<<1|1] = tree[rt];        tree[rt] = -1;    }}void updata(int rt,int begin,int end,int l,int r,int x){    if(begin>=l&&r>=end)    {        tree[rt] = x;        return ;    }    pushdown(rt);    int mid=(begin+end)>>1;    if(mid>=l) updata(lson,l,r,x);    if(r>mid) updata(rson,l,r,x);}void querry(int rt,int begin,int end){    if(begin==end)    {        if(tree[rt]>=0&&tree[rt]!=pre)        {            ans[tree[rt]]++;        }        pre=tree[rt]; return;    }    pushdown(rt);    int mid=(begin+end)>>1;    querry(lson); querry(rson);}int main(){    int m;    while(scanf("%d",&m)!=EOF)    {        memset(tree,-1,sizeof(tree));        memset(ans,0,sizeof(ans));        for(int i=1;i<=m;++i)        {           int a,b,c;           scanf("%d%d%d",&a,&b,&c);           if(b>a)updata(1,1,8000,a+1,b,c);        }        pre=-1;        querry(1,1,8000);        for(int i=0;i<=8000;++i)        {            if(ans[i])            {                printf("%d %d\n",i,ans[i]);            }        }        printf("\n");    }    return 0;}






原创粉丝点击