hdu1556解题报告

来源:互联网 发布:maya软件下载 编辑:程序博客网 时间:2024/06/05 07:26

题目大意:N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?

解题思路:线段树,直接弄即可

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn=100000+1000;int n,sumv[maxn*4+1000],addv[maxn*4+1000];int y1,y2,_sumv,v;void maintain(int o,int L,int R){        int lc=o*2,lr=o*2+1;        sumv[o]=0;        if(R>L)        {                sumv[o]=sumv[lc]+sumv[lr];        }        sumv[o]+=addv[o]*(R-L+1);}void update(int o,int L,int R){        int lc=o*2,lr=o*2+1;        if(y1<=L&&y2>=R)   addv[o]+=v;        else{                int M=L+(R-L)/2;                if(y1<=M)                update(lc,L,M);                if(y2>M)                update(lr,M+1,R);        }        maintain(o,L,R);}void query(int o,int L, int R,int add){        if(y1<=L&&y2>=R)        _sumv+=sumv[o]+add*(R-L+1);        else        {               int M=L+(R-L)/2;               if(y1<=M) query(o*2,L,M,add+addv[o]);               if(y2>M)  query(o*2+1,M+1,R,add+addv[o]);        }}int main(){        while(scanf("%d",&n)&&n)        {                memset(sumv,0,sizeof(sumv));                memset(addv,0,sizeof(addv));                int tmp=n;                v=1;                while(tmp--)                {                        scanf("%d%d",&y1,&y2);                        update(1,1,n);                }                for(int i=1;i<=n;i++)                {                        _sumv=0;                        y1=y2=i;                        query(1,1,n,0);                        if(i!=n) printf("%d ",_sumv);                        else printf("%d\n",_sumv);                }        }        return 0;}


0 0
原创粉丝点击