• hdu 4638 Group


    http://acm.hdu.edu.cn/showproblem.php?pid=4638

    问题其实就是求[L,R]中有多少个连续的段

    若每一个人都是一个段 那么[L,R]中每一个朋友关系就会减少一个段(因为它将两个段合并了)

    我们把每个朋友关系变成一个边 要求[L,R]有多少个边 可以用到 离散化+树状数组

    把每个朋友关系形成的边以左端点为key从大到小排序 遍历时将右端点不断的插入

    当左端点为key的边全部插入的时候 那么所有[L,R]中L等于key的询问都可求了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<list>
    #include<stack>
    #include<queue>
    using namespace std;
    
    typedef pair<int,int> pp;
    typedef long long ll;
    const int N=100005;
    int place[N];
    int a[N];
    struct node
    {
        int index;
        int l,r;
    }q[N];
    vector<int>vt[N];
    int ans[N];
    int c[N];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int i)
    {
        while(i<N)
        {
            c[i]+=1;
            i+=lowbit(i);
        }
    }
    int get(int i)
    {
        int tmp=0;
        while(i>=1)
        {
            tmp+=c[i];
            i-=lowbit(i);
        }
        return tmp;
    }
    
    bool cmp(node x,node y)
    {
        return x.l>y.l;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
           memset(c,0,sizeof(c));
           for(int i=0;i<N;++i)
           vt[i].clear();
           memset(place,-1,sizeof(place));
           int n,m;
           scanf("%d %d",&n,&m);
           for(int i=1;i<=n;++i)
           {
               scanf("%d",&a[i]);
               place[a[i]]=i;
           }
           for(int i=1;i<=n;++i)
           {
               int k=a[i];
               int l,r;
               if(place[k+1]!=-1)
               {l=min(place[k+1],i);r=max(place[k+1],i);vt[l].push_back(r);}
           }
           for(int i=0;i<m;++i)
           {
               scanf("%d %d",&q[i].l,&q[i].r);
               q[i].index=i;
           }
           sort(q,q+m,cmp);
           int I=0;
           for(int i=n;i>=1;--i)
           {
               for(unsigned int j=0;j<vt[i].size();++j)
               {
                    add(vt[i][j]);
               }
               while(I<m&&q[I].l==i)
               {
                   ans[q[I].index]=q[I].r-q[I].l+1-get(q[I].r);
                   ++I;
               }
           }
           for(int i=0;i<m;++i)
           printf("%d
    ",ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    web攻击
    HTTP与HTTPS
    HTTP确认访问用户身份的认证
    Http协议(三)返回结果的HTTP状态码
    HTTP协议四(http首部)
    HTTP协议(二)报文信息
    HTTP协议(一)
    Windows10 如何设置软件开机自起动和关闭
    获取Chrome版本并下载匹配的chromedriver
    多线程Runnable
  • 原文地址:https://www.cnblogs.com/liulangye/p/3230713.html
Copyright © 2020-2023  润新知