• codeforces722——C.Destroying Array(并查集+栈+逆向思维)


    原题链接
    题意:
    在这里插入图片描述
    思路:
    正着删除不好维护,我们考虑倒着加数。
    加入的时候合并左边元素和右边元素在的连续序列,更新答案。
    因为要倒序输出,可以用栈来维护。
    合并可以用并查集。
    注意刚开始的时候要加入0,即删完所有元素后答案一定是0.
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll>PLL;
    typedef pair<int,int>PII;
    typedef pair<double,double>PDD;
    #define I_int ll
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    char F[200];
    inline void out(I_int x)
    {
        if (x == 0) return (void) (putchar('0'));
        I_int tmp = x > 0 ? x : -x;
        if (x < 0) putchar('-');
        int cnt = 0;
        while (tmp > 0)
        {
            F[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while (cnt > 0) putchar(F[--cnt]);
        //cout<<" ";
    }
    ll ksm(ll a,ll b,ll p)
    {
        ll res=1;
        while(b)
        {
            if(b&1)res=res*a%p;
            a=a*a%p;
            b>>=1;
        }
        return res;
    }
    const ll inf = 0x3f3f3f3f3f3f3f3f;
    const int maxn=100000+100,mod=1e8;
    const double PI = atan(1.0)*4;
    const double eps=1e-6;
    int a[maxn],op[maxn],n;
    int root[maxn];
    ll siz[maxn];
    stack<ll>res;
    int Find(int x){
        if(x!=root[x]) root[x]=Find(root[x]);
        return root[x];
    }
    void Union(int u,int v){
        u=Find(u),v=Find(v);
        if(u!=v){
            siz[u]+=siz[v];
            siz[v]=0;
            root[v]=u;
        }
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++) op[i]=read();
        ll maxx=0;
        res.push(maxx);
        for(int i=n;i>1;i--){///倒着开始添加元素
            if(!root[op[i]]){
                root[op[i]]=op[i];siz[op[i]]=a[op[i]];
            }
            if(op[i]-1>=1&&root[op[i]-1]){
                Union(op[i],op[i]-1);
            }
            if(op[i]+1<=n&&root[op[i]+1]){
                Union(op[i],op[i]+1);
            }
            maxx=max(maxx,siz[op[i]]);
            res.push(maxx);
        }
        while(!res.empty()){
            printf("%lld
    ",res.top());
            res.pop();
        }
        return 0;
    }
    
    
  • 相关阅读:
    视图&索引&序列
    PL/SQL语言基础
    C#实现递归矩阵连乘(动态规划的递归自顶向下,非递归自地向上)
    JS 第五课
    请问,小丽的鞋子到底是什么颜色的?
    用10!来回顾 PL/SQL语言基础 && 标准异常名
    SELECT 查询—子查询
    备份和恢复
    JS 第六课
    Linux学习之二Linux系统的目录结构
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853073.html
Copyright © 2020-2023  润新知