zoukankan      html  css  js  c++  java
  • 与众不同

    鬼知道我为什么二分的时候传了个常量进去当左右端点还能过样例啊,不是样例就应该直接TLE吗?,调了好久

    题意是这样的:给定一个长为n的序列a,再给定m个区间 [(l_i,r_i)] 。对于每个区间输出该区间内最长的子序列并且这个子序列没有重复的元素。

    对于全部数据,(1le n,m≤2cdot 10^5,0le l_ile r_ile N−1,|ai|le 10^6)

    思路:
    像这种没有重复数字的询问有很多都是记录这个数字上次出现的位置,然后再加一些其他的操作的。这题也是,用last[i]表示i最近一次出现的位置,st[i]表示以i为右端点的最长满足条件的起点,则 st[i]=max(st[i-1],last[a[i]]+1) ,设f[i]=i-st[i]+1(就是长度啦).

    将[(l_i,r_i)]内的点分成2类:st[i](ge l_i) 的和不属于第1类的。由于st[i]单调不降,所以一定可以找到一个位置tmp,使得[(l_i,tmp-1)]是第二类点,[(tmp,r_i)] 是第一类点。

    对于第一类位置,直接找 (max){(f_i)} ((l_ile i le r_i)) 就是答案。用ST表维护一下即可.

    对于第二类位置,(tmp-l_i)即为答案。

    #include<cstdio>
    using namespace std;
    const int M=1000005;
    const int N=200005;
    int last[M<<1],st[N],f[N],mx[N][19],log[N];
    inline int max(const int &x,const int &y){return x>y?x:y;}
    int find(int l,int r)
    {
        if(st[l]==l)return l;
        if(st[r]<l)return r+1;
        int res=l,ll=l,rr=r;
        while(ll<=rr)
        {
            int mid=(ll+rr)>>1;
            if(st[mid]<l)ll=mid+1;
            else res=mid,rr=mid-1;
        }
        return res;
    }
    int query(int l,int r)
    {
        int lo=log[r-l+1];
        return max(mx[l][lo],mx[r-(1<<lo)+1][lo]);
    }
    int n,m;
    int main()
    {
        scanf("%d%d",&n,&m);log[0]=-1;
        for(int i=1,x;i<=n;++i)
        {
            scanf("%d",&x);
            st[i]=max(st[i-1],last[x+M]+1);
            last[x+M]=i;
            f[i]=i-st[i]+1;
            log[i]=log[i>>1]+1;
            mx[i][0]=f[i];
        }
        for(int j=1;j<=18;++j)
            for(int i=1;i+(1<<j)-1<=n;++i)
                mx[i][j]=max(mx[i][j-1],mx[i+(1<<j-1)][j-1]);
        for(int i=1,ql,qr;i<=m;++i)
        {
            scanf("%d%d",&ql,&qr);
            ++ql,++qr;
            int tmp=find(ql,qr),ans;
            ans=tmp-ql;
            if(tmp<=qr)ans=max(ans,query(tmp,qr));
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    最大连续序列和
    打印有序链表的公共部分
    字符串最长子串大小
    jvm简介
    大浮点数乘法
    java代码的快速排序理解
    从内存分配分析程序初始化和存储
    时间复杂度
    Filter&Listener
    MVC开发模式&EL表达式&JSTL&三层架构开发
  • 原文地址:https://www.cnblogs.com/zzctommy/p/12342078.html
Copyright © 2011-2022 走看看