zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 55 E 分治

    题意:一个数组,选一个连续区间[L,R] 使得 区间内相同的数 + 区间外a[i]=c的个数最多

    思路:似乎可以o(n),这里提供一个O(nogn)的分治方法,这类只选一个区间的问题很容易想到分治法,难在如何合并左右区间,这里我们贪心合并即可(枚举L,R的相同的数取什么),维护一下 左右可并的每种a[i] 的最优答案。可能表述不清,详细见代码。

    代码:

    #include<bits/stdc++.h>
    #define PB push_back
    #define X first
    #define Y second
    #define FIO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    typedef long long ll;
    typedef double LD;
    typedef pair<int,int> pii;
    const int maxn=5e5+10;
    const ll inf=1e9+7;
    ll t,n,m,x,y,b,c;
    int a[maxn];
    struct P{
        int c_cnt=0,res=0;
    };
    P ans[maxn*4];
    int LM[maxn];
    int Lbest[maxn],Rbest[maxn];
    int solve(int L,int R,int rt,int flag){
        int mid=(L+R)/2;
        if(L==R){
            ans[rt].c_cnt=(a[L]==c);
            return ans[rt].res=1;
        }
        solve(L,mid,rt*2,2);
        solve(mid+1,R,rt*2+1,1);
        ans[rt].res=ans[rt*2].c_cnt+ans[rt*2+1].c_cnt;
        ans[rt].res=max(ans[rt].res,ans[rt*2].res+ans[rt*2+1].c_cnt);
        ans[rt].res=max(ans[rt].res,ans[rt*2+1].res+ans[rt*2].c_cnt);
        ans[rt].c_cnt=ans[rt*2].c_cnt+ans[rt*2+1].c_cnt;
        int tmpc=0;
        for(int i=L;i<=R;++i)LM[a[i]]=Lbest[a[i]]=0;
        for(int i=mid+1;i<=R;++i){
            if(a[i]==c) tmpc++;
            LM[a[i]]++;
            if(LM[a[i]]+ans[rt*2+1].c_cnt-tmpc>Lbest[a[i]])
                Lbest[a[i]]=LM[a[i]]+ans[rt*2+1].c_cnt-tmpc;
        }
        for(int i=L;i<=R;++i)LM[a[i]]=Rbest[a[i]]=0;
        tmpc=0;
        for(int i=mid;i>=L;--i){
            if(a[i]==c) tmpc++;
            LM[a[i]]++;
            if(LM[a[i]]+ans[rt*2].c_cnt-tmpc>Rbest[a[i]]){
                Rbest[a[i]]=LM[a[i]]+ans[rt*2].c_cnt-tmpc;
                ans[rt].res=max(ans[rt].res,Rbest[a[i]]+Lbest[a[i]]);
            }
        }
        return ans[rt].res;
    }
    
    int main(){
        FIO;
        cin>>n>>c;
        for(int i=1;i<=n;i++)cin>>a[i];
        cout<<solve(1,n,1,0)<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Dp~Hrbust1426( 集训队的晚餐 )
    DP~数塔(hrbustoj1004)
    MyEclipse启动性能优化(----加快启动速度)
    很实用的php的缓存类文件示例
    PHP中9大缓存技术总结
    微信公众平台开发(76) 获取用户基本信息
    js中 onreadystatechange 和 onload的区别
    一个js文件导入js的函数
    PHP cURL实现模拟登录与采集使用方法详解教程
    Mysql清空表(truncate)与删除表中数据(delete)的区别
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672474.html
Copyright © 2011-2022 走看看