zoukankan      html  css  js  c++  java
  • HDU 5919 分块做法

    题意和链接前面的blog有,就不再提。。

    思路:本来实在是莽不过去。。后来想到其实复杂度均摊下来每块取比sqrt(n)大一些更好。。具体大多少。。嗯。。大概x^2/logx=N  。?我也不会解。。。

    所以n取了个2*sqrt(n)结果卡过去了。。。重要的还是思想。。分块后每块排序,和3333套路差不多,时间复杂度O(n*sqrt(n)*log(n))复杂度一看就不小。。不过编码很简单暴力。。毕竟数据结构实在写不了也可以莽一下嘛。。。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int MAXN = 200010;
    int n,q,block,num;
    int a[MAXN];
    int belong[MAXN],L[MAXN],R[MAXN],c[MAXN],d[MAXN],mp[MAXN],tmp[MAXN];
    
    int build(int n){
        block=sqrt(n)*2;
        num=n/block;
        if(n%block!=0) num++;
        for(int i=0;i<num;i++){
            L[i]=i*block+1;
            R[i]=(i+1)*block;
        }
        R[num-1]=n;
        int cnt=0;
        for(int i=1;i<=n;i++){
            if(i<=R[cnt]) belong[i]=cnt;
            else belong[i]=++cnt;
        }
        memset(mp,0,sizeof(mp));
        for(int i = 1; i<= n; i++){
            c[i]=mp[a[i]];
            mp[a[i]] = i;
        }
        for(int i=1;i<=n;i++) d[i]=c[i];
        for(int i=0;i<num;i++){
            sort(c+L[i],c+R[i]+1);
        }
    }
    
    int query(int l,int r){
        int ret=0;
        if(belong[l]==belong[r]){
            for(int i=l;i<=r;i++){
                if(d[i]<l) ++ret;
            }
            int x=(ret+1)/2;
            ret=0;
            for(int i=l;i<=r;i++){
                if(d[i]<l) ++ret;
                if(ret==x) return i;
            }
        }
        for(int i=l;i<=R[belong[l]];i++){
            if(d[i]<l) ++ret;
        }
        for(int i=belong[l]+1;i<belong[r];i++){
            tmp[i]=(int)(lower_bound(c+L[i],c+R[i]+1,l)-c)-L[i];
            ret+=tmp[i];
        }
        for(int i=L[belong[r]];i<=r;i++){
            if(d[i]<l) ++ret;
        }
        int x=(ret+1)/2;
        ret=0;
        for(int i=l;i<=R[belong[l]];i++){
            if(d[i]<l) ++ret;
            if(ret==x) return i;
        }
        for(int i=belong[l]+1;i<belong[r];i++){
            int tm=ret;
            ret+=tmp[i];
            if(ret>=x){
                for(int j=L[i];j<=R[i];j++){
                    if(d[j]<l) ++tm;
                    if(tm==x) return j;
                }
            }
        }
        for(int i=L[belong[r]];i<=r;i++){
            if(d[i]<l) ++ret;
            if(ret==x) return i;
        }
    }
    
    int Q[MAXN];
    
    int main(){
        Q[0]=0;
        int t,cas=1;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&q);
            for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
            build(n);
            int l,r;
            for(int i=1;i<=q;i++){
                scanf("%d%d",&l,&r);
                l=(l+Q[i-1])%n+1;
                r=(r+Q[i-1])%n+1;
                if(r<l) swap(l,r);
                Q[i]=query(l,r);
            }
            printf("Case #%d:",cas++);
            for(int i=1;i<=q;i++) printf(" %d",Q[i]);
            printf("
    ");
        }
        return 0;
    }
    



  • 相关阅读:
    XML基础介绍【二】
    XML基础介绍【一】
    Java面向对象(三) 【面向对象深入:抽象类,接口,内部类等】
    Java面向对象(二)
    Java面向对象(一)
    main特别之处
    c语言线性表
    c语言三元组
    线性表(顺序表的创建)
    创建一个三元组
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672532.html
Copyright © 2011-2022 走看看