• 乱搞+虚假莫队?+树状数组——cf1288E


    感觉自己的解法有点歪

    /*
    每次把一个数提到最前面,问整个过程结束后1..n每个数出现最靠前的位置和最靠后的位置
    最靠前:如果一个数被提前过,那么必然是1
            如果从来没被提前过,就是其原来的位置
    最靠后:维护数i每次被提前的时间序列time[i][]
        time[i][1]到time[i][2]之间出现不同元素的个数就是其在这一段时间内i最靠后的位置
        i出现的最靠后位置就是所有这种位置取max,再和初始值取max 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 600005
    
    int n,m,a[N],Max[N],flag[N],Min[N];
    vector<int>times[N];
    int q,block; 
    struct Query{
        int l,r,col;
    }Q[N];
    int cmp(Query a,Query b){
        if(a.l/block == b.l/block)return a.r<b.r;
        return a.l<b.l;
    }
    
    int cnt[N],tot;
    void add(int x){
        cnt[a[x]]++;
        if(cnt[a[x]]==1)tot++;
    } 
    void del(int x){
        cnt[a[x]]--;
        if(!cnt[a[x]])tot--; 
    }
    
    int c[N],vis[N];
    void update(int x){
        while(x<=n){
            c[x]++;
            x+=x&-x;
        }
    } 
    int query(int x){
        int res=0;
        while(x){
            res+=c[x];
            x-=x&-x;
        }
        return res;
    }
    
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)Max[i]=Min[i]=i;
        for(int i=1;i<=m;i++){
            cin>>a[i];
            flag[a[i]]=1;
        }
        for(int i=1;i<=n;i++)if(flag[i])Min[i]=1;
        
        for(int i=1;i<=m;i++){//每个数前有多少比其大的 
            if(vis[a[i]])continue;
            vis[a[i]]=1;
            Max[a[i]]+=query(n)-query(a[i]);
            update(a[i]);    
        }
        for(int i=1;i<=n;i++)
            if(!vis[i]){
                Max[i]+=query(n)-query(i);
            }
        
        for(int i=1;i<=m;i++)times[a[i]].push_back(i);
        for(int i=1;i<=n;i++)times[i].push_back(m+1);
        for(int i=1;i<=n;i++){
            for(int j=0;j<times[i].size()-1;j++){
                int l=times[i][j]+1,r=times[i][j+1]-1;
                if(l<=r){
                    ++q;Q[q].l=l;Q[q].r=r;Q[q].col=i;
                }
            }    
        }
        
        block=sqrt(m);
        sort(Q+1,Q+1+q,cmp);
        
        int L=1,R=0;
        for(int i=1;i<=q;i++){
            while(L>Q[i].l)add(--L);
            while(R<Q[i].r)add(++R);
            while(L<Q[i].l)del(L++);
            while(R>Q[i].r)del(R--);
            Max[Q[i].col]=max(tot+1,Max[Q[i].col]);
        }
        
        for(int i=1;i<=n;i++)cout<<Min[i]<<" "<<Max[i]<<'
    ';
    }
     
  • 相关阅读:
    JDK5后的特性整理
    正向代理与反向代理的区别与异同
    我所用过的nginx的功能
    网页端消息推送之推与拉
    在一个py脚本中调用另外一个py脚本中的类或函数
    import与from ... import ...的区别
    python 读取文件
    shell中的特殊变量IFS
    shell 重定向以及文件描述符
    shell下读取文件数据
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12270996.html
Copyright © 2020-2023  润新知