zoukankan      html  css  js  c++  java
  • hdu6602---线段树

    Longest Subarray

    题意:一个数列,每个元素大小都在1到C之间,求一个最长的子串,满足在这个子串中1到C之间的每个数字要么出现0次,要么出现至少K次。

    题解:(i)从1到n枚举右端点,维护一个(tree[j])表示在(i)为右端点时以(j)为左端点可行的个数(这里的可行是指对于1到C之间的某一个数是否可行,即(j)(i)之间(X)的个数是否满足题意,(Xepsilon(1,C)))。那么对于固定的(i)显然当(tree[j]==C)([j,i])是一个可行区间,找出最小的(j)即可. 上述操作在线段树上维护.

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100005;
    int n,c,k,a[100005];
    int tree[maxn*4],tag[maxn*4];
    inline int ls(int x){
        return x<<1;
    }
    inline int rs(int x){
        return x<<1|1;
    }
    void change(int root,int del){
        tree[root]+=del;
        tag[root]+=del;
    }
    void pushdown(int root,int l,int r){
        if(!tag[root]) return;
        int mid=(l+r)>>1;
        change(ls(root),tag[root]);
        change(rs(root),tag[root]);
        tag[root]=0;
    }
    void update(int root,int l,int r,int il,int ir,int del){
        if(r<il||l>ir) return;
        if(l>=il&&r<=ir) {
            tree[root] += del;
            tag[root] += del;
            return;
        }
        pushdown(root,l,r);
        int mid=(l+r)>>1;
        update(ls(root),l,mid,il,ir,del);
        update(rs(root),mid+1,r,il,ir,del);
        tree[root]=max(tree[ls(root)],tree[rs(root)]);
    }
    int ask(int root,int l,int r,int il,int ir){
        if(r<il||l>ir) return -1;
        if(tree[root]<c) return -1;
        if(l==r) return l;
        pushdown(root,l,r);
        int mid=(l+r)>>1;
        int tmp=ask(ls(root),l,mid,il,ir);
        if(tmp>0) return tmp;
        return ask(rs(root),mid+1,r,il,ir);
    }
    vector<int> pos[maxn];
    int main(){
        while(~scanf("%d%d%d",&n,&c,&k)) {
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            for(int i=1;i<=c;i++) {
                pos[i].clear();
            }
            if(k==1){
                printf("%d
    ",n); continue;
            }
            int nn=n*4;
            for(int i=1;i<=nn;i++) tree[i]=0,tag[i]=0;
            int ans=0;
            for(int i=1;i<=n;i++){
                pos[a[i]].push_back(i);
                update(1,1,n,i,i,c-1);
                int siz=pos[a[i]].size();
                if(siz>=1){
                    int l=siz-2,r=siz-1;
                    if(l<0) l=1;
                    else l=pos[a[i]][l]+1;
                    r=pos[a[i]][r]-1;
                    if(l<=r) update(1,1,n,l,r,-1);
                }
                if(siz>=k){
                    int l=siz-k-1,r=siz-k;
                    if(l<0) l=1;
                    else l=pos[a[i]][l]+1;
                    r=pos[a[i]][r];
                    update(1,1,n,l,r,1);
                }
                int tmp=ask(1,1,n,1,i);
                if(tmp>0) ans=max(ans,i-tmp+1);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    推荐一篇好文加上一些补充
    我也来写一个俄罗斯方块
    使用canvas绘制一个时钟
    断句:Store all parameters but the first passed to this function as an array
    Observer Pattern
    web worker 的 self
    练练断句
    as 什么意思?
    natively 在本地机器
    in mind (不是 切记 的意思)
  • 原文地址:https://www.cnblogs.com/vege-chicken-rainstar/p/11503606.html
Copyright © 2011-2022 走看看