浏览器标题切换
浏览器标题切换end

HDU1556 - Color the ball - 前缀和/线段树/树状数组

思路

周赛的一开始直接用book进行标记,后来TLE,然后改成map,继续TLE
  
后来想到用线段树写,但是没写对;想用树状数组写,结果发现不会写

AC代码(前缀和)

//前缀和的做法
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

const int N=100020;

int a[N];
int sum[N];
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        memset(a,0,sizeof(a));
        int aa,bb;
        for(int i=0; i<n; i++)
        {
            scanf("%d %d",&aa,&bb);
//            a[aa]=a[aa]+1;
//            a[bb+1]=a[bb+1]-1;
            a[aa]++;
            a[bb+1]--;
        }

        //求前缀和
        sum[0]=0;
        for(int i=1;i<=n;i++)
            sum[i]=sum[i-1]+a[i];
        for(int i=1;i<n;i++)
            printf("%d ",sum[i]);
        printf("%d\n",sum[n]);
    }
    return 0;
}

AC代码(线段树)

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=100020;

int a[4*N];
int ans[4*N];
int p;

//void pushdown(int i,int len)
//{
//    if(lazy[i])
//    {
//        lazy[i<<1]=lazy[i];
//        lazy[i<<1|1]=lazy[i];
//        a[i<<1]=(len-(len>>1))*lazy[i];
//        a[i<<1|1]=(len>>1)*lazy[i];
//        lazy[i]=0;
//    }
//}
void pushdown(int i)
{
    a[i<<1]+=a[i];
    a[i<<1|1]+=a[i];
}

//void build(int L,int R,int i)
//{
//    if(L==R)
//    {
//        a[i]=0;
//        return;
//    }
//    int mid=(L+R)>>1;
//    build(L,mid,i<<1);
//    build(mid+1,R,i<<1|1);
//    a[i]=a[i<<1]+a[i<<1|1];
//}

void update(int left,int right,int L,int R,int i)
{
    if(left<=L&&right>=R)
    {
//        lazy[i]+=1;
//        a[i]=R-L+1;
        a[i]++;
        return;
    }
//    pushdown(i,R-L+1);
    int mid=(R+L)>>1;
    if(left<=mid)
        update(left,right,L,mid,i<<1);
    if(right>mid)
        update(left,right,mid+1,R,i<<1|1);
//    a[i]=a[i<<1]+a[i<<1|1];
}

void query(int L,int R,int i)
{
    if(L==R)
    {
        ans[p++]=a[i];
        return;
    }
    int mid=(L+R)>>1;
    pushdown(i);
    query(L,mid,i<<1);
    query(mid+1,R,i<<1|1);
}

int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        memset(a,0,sizeof(a));
        memset(ans,0,sizeof(ans));
//            build(1,n,1);
        int aa,bb;
        p=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d %d",&aa,&bb);
//            if(aa==bb)
//            {
//                a[aa]++;
//                continue;
//            }
            update(aa,bb,1,n,1);
        }
        query(1,n,1);
        for(int i=0; i<n-1; i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n-1]);
    }
    return 0;
}
posted @ 2019-09-09 22:01  抓水母的派大星  阅读(215)  评论(0编辑  收藏  举报