hdu1556区间问题(前缀和,树状数组,线段树)

题目链接:hdu1556


解法一,前缀和:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include<stdlib.h>
#include <queue>
#include <set>
#include <vector>
#define MAX 100005
#define inf 0x3f3f3f3f
using namespace std;

int vis[MAX];
int main()
{
	int N,i,a,b;
	while(scanf("%d",&N)!=EOF)
	{
		
		if (!N) break;  
		for (i=1;i<=N;i++)
		{
			scanf("%d%d",&a,&b);
			vis[a]++;
			vis[b+1]--;
		}
		for (i=1;i<=N;i++)
		{
			vis[i]+=vis[i-1];
		}
		for (i=1;i<=N;i++)
		{
			if (i!=1) printf(" ");
			printf("%d",vis[i]);
		}
		printf("\n");
		for (i=1;i<=N+1;i++)
		{
			vis[i]=0;
		}
		
	}
	
	return 0;
	
}

解法二,树状数组

#include<bits/stdc++.h>
using namespace std;
const int M=100000;
int c[M];
int lowbit(int t)
{
    return t&(-t);
}
void add(int x,int val)
{
    while(x<=M)
    {
        c[x]+=val;
        x+=lowbit(x);
    }
}
int sum(int x)
{
    int ans=0;
    while(x)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n,n)
    {
        memset(c,0,sizeof(c));
        int a,b;
        for(int i=0;i<n;i++)
        {
            cin>>a>>b;
            add(a,1);
            add(b+1,-1);
        }
        for(int k=1;k<n;k++)
            printf("%d ",sum(k));
        printf("%d\n",sum(n));
    }
    return 0;
}

解法3,线段树:

#include<bits/stdc++.h>
using namespace std;
#define maxn 100001
int ans[maxn];
struct node{
    int r,l,num;
}tree[maxn*4];
void build(int a,int b,int o)
{
    tree[o].l=a;
    tree[o].r=b;
    tree[o].num=0;
    if(a==b)return ;
    int m=(a+b)/2;
    build(a,m,o<<1);
    build(m+1,b,o<<1|1);
}
void color(int a,int b,int o)
{
    if(tree[o].l==a&&tree[o].r==b){tree[o].num++;return;}
    else if(b<=tree[o<<1].r)color(a,b,o<<1);
    else if(a>=tree[o<<1|1].l)color(a,b,o<<1|1);
    else {
        color(a,tree[o<<1].r,o<<1);
        color(tree[o<<1|1].l,b,o<<1|1);
    }
}
void add(int o)
{
    if(tree[o].num)
    for(int i=tree[o].l;i<=tree[o].r;i++)ans[i]+=tree[o].num;
    if(tree[o].l==tree[o].r)return;
    add(o<<1);
    add(o<<1|1);
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n,n)
    {
        int x,y;
        build(1,n,1);
        for(int i=0;i<n;i++)
        {
            cin>>x>>y;
            color(x,y,1);
        }
        memset(ans,0,sizeof(ans));
        add(1);
        for(int i=1;i<=n;i++)
        {
            if(i!=1)cout<<' ';
            cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/reallsp/article/details/79602253
今日推荐