• 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;
    }
    
  • 相关阅读:
    作业07-Java GUI编程
    作业06-接口、内部类
    作业05-继承、多态、抽象类与接口
    作业14-数据库
    作业13-网络
    作业12-流与文件
    作业11-多线程
    作业10-异常
    作业09-集合与泛型
    作业08-集合
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672474.html
Copyright © 2020-2023  润新知