• BZOJ 4003 城池攻占


    可并堆。打标记。

    注意细节。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #define maxv 300500
    #define maxe 300500
    using namespace std;
    struct edge
    {
        long long v,nxt;
    }e[maxe];
    set <long long> s[maxv];
    set <long long> ::iterator it;
    long long n,m,h[maxv],fath[maxv],a[maxv],v[maxv],w[maxv],c[maxv],val[maxv];
    long long tree[maxv][3],dfl[maxv],dis[maxv],nume=0,l1[maxv],l2[maxv];
    long long ans1[maxv],ans2[maxv],top[maxv],g[maxv];
    bool vis[maxv];
    void addedge(long long u,long long v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void pushdown(long long x)
    {
        long long ls=tree[x][1],rs=tree[x][2];
        l1[ls]=l1[ls]*l2[x]+l1[x];
        l1[rs]=l1[rs]*l2[x]+l1[x];
        l2[ls]*=l2[x];
        l2[rs]*=l2[x];
        val[ls]=val[ls]*l2[x]+l1[x];
        val[rs]=val[rs]*l2[x]+l1[x];
        l1[x]=0;l2[x]=1;
    }
    void pushup(long long x)
    {
        long long ls=tree[x][1],rs=tree[x][2];
        if (dfl[ls]<dfl[rs]) swap(tree[x][1],tree[x][2]);
        if (rs==0) dfl[x]=0;
        else dfl[x]=dfl[rs]+1;
    }
    long long merge(long long a,long long b)
    {
        if (a==0) return b;
        if (b==0) return a;
        if (val[a]>val[b]) swap(a,b);
        pushdown(a);
        tree[a][2]=merge(tree[a][2],b);
        pushup(a);
        return a;
    }
    long long pop(long long x)
    {
        long long ls=tree[x][1],rs=tree[x][2];
        pushdown(x);
        tree[x][1]=0;tree[x][2]=0;
        return merge(ls,rs);
    }
    void dfs1(long long x)
    {
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            dis[v]=dis[x]+1;
            dfs1(v);
        }
    }
    void dfs2(long long x)
    {
        for (long long i=g[x];i;i=e[i].nxt)
            dfs2(e[i].v);
        long long root=-1;
        for (it=s[x].begin();it!=s[x].end();it++)
        {
            long long now=*it;
            if (root==-1) root=now;
            else root=merge(root,now);
        }
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if (top[v]<=0) continue;
            if (root==-1) root=top[v];
            else root=merge(root,top[v]);
        }
        long long cnt=0;
        while ((val[root]<h[x]) && (root>=1))
        {
            ans2[root]=dis[c[root]]-dis[x];
            vis[root]=true;
            root=pop(root);
            cnt++;
        }    
        ans1[x]=cnt;
         if (a[x]==0) {l1[root]+=v[x];val[root]+=v[x];}
        else {l2[root]*=v[x];l1[root]*=v[x];val[root]*=v[x];}
         top[x]=root;
    }
    int main()
    {
        memset(vis,false,sizeof(vis));
        scanf("%lld%lld",&n,&m);
        fill(l2+1,l2+m+1,1);
        for (long long i=1;i<=n;i++)
            scanf("%lld",&h[i]);
        for (long long i=2;i<=n;i++)
        {
            scanf("%lld%lld%lld",&fath[i],&a[i],&v[i]);
            addedge(fath[i],i);
        }
        for (long long i=1;i<=m;i++)
        {
            scanf("%lld%lld",&w[i],&c[i]);
            s[c[i]].insert(i);
            val[i]=w[i];
        }
        dfs1(1);
        dfs2(1);
        for (long long i=1;i<=n;i++) printf("%lld
    ",ans1[i]);
        for (long long i=1;i<=m;i++)
        {
            if ((ans2[i]==0) && (vis[i]==false)) printf("%lld
    ",dis[c[i]]+1);
            else printf("%lld
    ",ans2[i]);
        }
        return 0;
    }
  • 相关阅读:
    Unity apk开机自启动一次
    Unity调用Android
    实验 1 Linux 系统的安装和常用命令
    课堂测试3第一阶段数据清洗
    Tutorial_6 运行结果
    Command 'ifconfig' not found, but can be installed with: sudo apt install net-tools VM Ubuntu 解决方案
    《规划极限编程》阅读笔记03
    软件工程_个人课程总结
    《规划极限编程》阅读笔记02
    学习进度_第十六周
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5490158.html
Copyright © 2020-2023  润新知