zoukankan      html  css  js  c++  java
  • hdu 5775

    对1~n的乱序数冒泡排序过程,求解每一个数能到达的最左和最右的位置差

    本质就是求解每一个数右边有多少小于他的数,加上现在的位置既是能到达的最右位置,最左位置很直观

    用树状数组或者线段树

    渣渣现在才发现代码里的线段树比硬来时间复杂度低

    线段树代码

    #include <iostream>
    #include <map>
    #include <math.h>
    #include <algorithm>
    #include <vector>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include<stdio.h>
    
    using namespace std;
    const int N=1e5+10;
    const int M=1e9+7;
    int g[N*4],t,cnt,n,a[N],num[N],b[N];
    void buildtree(int l,int r,int u)//建树
    {
        if(l==r)
        {
            g[u]=0;
            return ;
        }
        int mid=(l+r)/2;
        buildtree(l,mid,u*2);
        buildtree(mid+1,r,u*2+1);
        g[u]=0;
    }
    int query(int l,int r,int x,int y,int cnt)//查询
    {
        if(l>=x&&r<=y)
            return g[cnt];
        int mid=(l+r)/2;
        int k1=0,k2=0;
        if(mid>=x)
            k1=query(l,mid,x,y,cnt*2);
        if(mid<y)
            k2=query(mid+1,r,x,y,cnt*2+1);
        return k1+k2;
    }
    void update(int l,int r,int x,int cnt)//更新
    {
        if(l==x&&l==r)
        {
            g[cnt]=1;
            return ;
        }
        int mid=(l+r)/2;
        if(x<=mid){
            update(l,mid,x,cnt*2);
        g[cnt]+=1;
        }
         if(x>mid){
            update(mid+1,r,x,cnt*2+1);
        g[cnt]+=1;
         }
    }
    int main()
    {
        freopen("in.txt","r",stdin);
    
        cin>>t;
        int cas=0;
        while(t--)
        {
            cas++;
            scanf("%d",&n);
            int i;
            buildtree(1,n,1);
    
            for(i=1; i<=n; i++)
                scanf("%d",&a[i]);
    
            for(i=n; i>0; i--)
            {
                if(a[i]==1)
                    num[i]=0;
                else
                    num[i]=query(1,n,1,a[i]-1,1);
                //cout<<"r"<<endl;
                update(1,n,a[i],1);
                //cout<<"r"<<endl;
                //cout<<num[i]<<" ";
            }
    
            printf("Case #%d: ",cas);
    
            for(i=1; i<=n; i++)
            {
               int k1=num[i]+i;
               int k2=i;
               int k3=a[i];
                b[a[i]]=max(max(k1,k2),k3)-min(min(k1,k2),k3);
            }
            for(i=1; i<n; i++)
                printf("%d ",b[i]);
            printf("%d
    ",b[n]);
    
        }
        return 0;
    }

    树状数组

    #include <iostream>
    #include <map>
    #include <math.h>
    #include <algorithm>
    #include <vector>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include<stdio.h>
    using namespace std;
    const int N=100010;
    const int M=1e9+7;
    int a[N],tree[N],t,n,b[N],num[N];
    void add(int k,int num){//对k位置的数加上num
        while(k<=n){
            tree[k]+=num;
            k+=k&(-k);
    
        }
    }
    int read(int k){//查询一到k位置a[i]的和
        int sum=0;
        while(k){
            sum+=tree[k];
            k-=k&(-k);
        }
        return sum;
    }
    int main()
    {
       // freopen("in.txt","r",stdin);
     cin>>t;
     int cas=0;
     while(t--){
       cas++;
        memset(tree,0,sizeof(tree));
        int i;
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%d",&a[i]);
    
        }
           for(i=1;i<=n;i++){
            if(a[i]==1)
                num[1]=0;
            else
                num[a[i]]=read(a[i]);
        add(a[i],1);
           }
        //cout<<"2"<<endl;
        for(i=1;i<=n;i++){
          int min1=min(i,a[i]);
          int max1=max(i+a[i]-1-num[a[i]],a[i]);
            b[a[i]]=max1-min1;
        }
        printf("Case #%d: ",cas);
        for( i = 1 ; i <=n ; i ++){
            if(i==n)
                printf("%d
    ",b[i]);
            else
                printf("%d ",b[i]);
        }
     }
        return 0;
    }
  • 相关阅读:
    JavaScript 各种遍历方式详解
    使用TortoiseGit操作分支的创建与合并
    前端实现图片压缩上传
    改变input的value值,同时在HTML中将value进行改变
    HTML中字体单位px pt em之间的转换
    解决PHP无法接收post超过1000个字段的问题
    解决微信不能扫描下载的问题
    实现类似于百度实时搜索将结果在下拉框中显示的功能
    Python导入路径含特殊字符的包
    大二秋学期记录
  • 原文地址:https://www.cnblogs.com/shimu/p/5720630.html
Copyright © 2011-2022 走看看