• hdu5124(树状数组+离散化)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5124

    题意:有n条线段,求被覆盖到次数最多的点的次数

    分析:

    1.可以转化成求前缀和最大的问题:将区间改成左闭右开(即右端点加1),排序,从左往右遍历,若为左端点则加一,右端点则减一。

    2.树状数组,离散化一下,然后区间更新,单点查询。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define inf 1<<30
    #define mod 1000000007
    using namespace std;
    int a[500010],n,m;
    int c[200010];
    struct node
    {
        int l,r;
    }s[100010];
    int bin(int key,int n,int a[])
    {
        int l=0,r=n-1;
        while(l<=r)
        {
            int m=(l+r)>>1;
            if(a[m]==key)return m;
            if(a[m]<key)l=m+1;
            else r=m-1;
        }
        return -1;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int cnt=0,l,r;
            memset(c,0,sizeof(c));
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&l,&r);
                s[i].l=l;s[i].r=r;
                a[cnt++]=l;a[cnt++]=r;
            }
            sort(a,a+cnt);
            m=1;
            //离散化好模板
            for(int i=1;i<cnt;i++)
                if(a[i]!=a[i-1])a[m++]=a[i];
            for(int i=m-1;i>=0;i--)
                if(a[i]!=a[i-1]+1)a[m++]=a[i-1]+1;
            sort(a,a+m);
            for(int i=1;i<=n;i++)
            {
                l=bin(s[i].l,m,a);
                r=bin(s[i].r,m,a);
               c[l]++;c[r+1]--;
            }
            int ans=0,sum=0;
            for(int i=0;i<m;i++)
            {
                sum+=c[i];
                ans=max(ans,sum);
            }
            printf("%d
    ",ans);
        }
    }
    View Code


     

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define inf 1<<30
    #define mod 1000000007
    using namespace std;
    int a[500010],n,m;
    int c[200010];
    struct node
    {
        int l,r;
    }s[100010];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int x,int d)
    {
        while(x)
        {
            c[x]+=d;
            x-=lowbit(x);
        }
    }
    int sum(int x)
    {
        int res=0;
        while(x<=m+1)
        {
            res+=c[x];
            x+=lowbit(x);
        }
        return res;
    }
    int bin(int key,int n,int a[])
    {
        int l=0,r=n-1;
        while(l<=r)
        {
            int m=(l+r)>>1;
            if(a[m]==key)return m;
            if(a[m]<key)l=m+1;
            else r=m-1;
        }
        return -1;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int cnt=0,l,r;
            memset(c,0,sizeof(c));
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&l,&r);
                s[i].l=l;s[i].r=r;
                a[cnt++]=l;a[cnt++]=r;
            }
            sort(a,a+cnt);
            m=1;
            //离散化好模板
            for(int i=1;i<cnt;i++)
                if(a[i]!=a[i-1])a[m++]=a[i];
            for(int i=m-1;i>=0;i--)
                if(a[i]!=a[i-1]+1)a[m++]=a[i-1]+1;
            sort(a,a+m);
            for(int i=1;i<=n;i++)
            {
                l=bin(s[i].l,m,a);
                r=bin(s[i].r,m,a);
                //树状数组习惯把区间右移了1,防止x+=lowbit(x)陷于死循环,不过这里加不是这个原因
                l+=2;r+=2;
                update(l-1,-1);update(r,1);
            }
            int ans=0;
            for(int i=2;i<=m+1;i++)ans=max(ans,sum(i));
            printf("%d
    ",ans);
        }
    }
    View Code

     当然不一定非得把坐标映射到x轴上,vextor<pair<int,int> >v;v[i].first用来把坐标排序,起到映射的作用。然后数组的下标就起到了压缩的作用。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define inf 1<<30
    #define mod 1000000007
    using namespace std;
    
    vector <pair<int,int> > v;
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            v.clear();
            int n;
            scanf("%d",&n);
            for (int i = 0; i < n; i++)
            {
                int x;
                scanf("%d",&x);
                v.push_back(make_pair(x,1));
                scanf("%d",&x);
                v.push_back(make_pair(x + 1,-1));
            }
            sort(v.begin(), v.end());
            int ans = 0;
            int sum = 0;
            for (int i = 0; i < v.size(); i++)
            {
                sum += v[i].second;
                ans = max(sum,ans);
            }
            printf("%d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    ubuntu,day1基础命令,shutdown,man,touch,rm,mv,cp,stat,locale,apt,date,tzselect,cal,快捷方式,echo,查看文件
    day 7 编码
    NO.6 appium-网络设置
    NO.5 appium-滑动和点击
    NO.4 appium-定位
    NO.3 appium-退出/启动
    NO.2 appium-安装和卸载
    NO.1 appium-关于输入法
    Springboot框架搭建
    遍历Map的四种方法
  • 原文地址:https://www.cnblogs.com/lienus/p/4132396.html
Copyright © 2020-2023  润新知