zoukankan      html  css  js  c++  java
  • JLOI2015 城池攻占

    题目描述

    题解:

    将所有骑士放在$ci$上,然后树上$dfs$。

    每个节点维护一个小根堆,一直$pop$直到$top>=hi$。

    然后放加法、乘法标记,将剩下的骑士回溯带回父节点。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 300050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,m,f[N],hed[N],cnt;
    ll h[N],a[N],v[N],s[N],c[N],tag_p[N],tag_m[N];
    int dis[N],ls[N],rs[N];
    int rt[N];
    struct EG
    {
        int to,nxt;
    }e[N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    void add(int x,ll d)
    {
        if(!x)return ;
        tag_p[x]+=d;
        s[x]+=d;
    }
    void mul(int x,ll d)
    {
        if(!x)return ;
        tag_m[x]*=d;
        tag_p[x]*=d;
        s[x]*=d;
    }
    void pushdown(int x)
    {
        if(tag_m[x]!=1)
        {
            mul(ls[x],tag_m[x]);
            mul(rs[x],tag_m[x]);
            tag_m[x] = 1;
        }
        if(tag_p[x])
        {
            add(ls[x],tag_p[x]);
            add(rs[x],tag_p[x]);
            tag_p[x] = 0;
        }
    }
    int merge(int x,int y)
    {
        if(!x||!y)return x+y;
        if(s[x]>s[y])swap(x,y);
        pushdown(x);
        rs[x] = merge(rs[x],y);
        if(dis[ls[x]]<dis[rs[x]])swap(ls[x],rs[x]);
        dis[x] = dis[rs[x]]+1;
        return x;
    }
    int pop(int x)
    {
        pushdown(x);
        return merge(ls[x],rs[x]);
    }
    int dep[N];
    int a1[N],a2[N];
    void dfs(int u)
    {
        dep[u] = dep[f[u]]+1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            dfs(to);
            rt[u]=merge(rt[u],rt[to]);
        }
        while(rt[u]&&s[rt[u]]<h[u])
        {
            a1[u]++;
            a2[rt[u]]=dep[c[rt[u]]]-dep[u];
            rt[u]=pop(rt[u]);
        }
        if(!a[u])add(rt[u],v[u]);
        else mul(rt[u],v[u]);
    }
    int main()
    {
        read(n),read(m);
        for(int i=1;i<=n;i++)read(h[i]);h[0]=10000000000000008ll;
        ae(0,1);
        for(int i=2;i<=n;i++)read(f[i]),read(a[i]),read(v[i]),ae(f[i],i);
        for(int i=1;i<=m;i++)read(s[i]),read(c[i]),tag_m[i]=dis[i]=1,rt[c[i]]=merge(rt[c[i]],i);
        dfs(0);
        for(int i=1;i<=n;i++)printf("%d
    ",a1[i]);
        for(int i=1;i<=m;i++)printf("%d
    ",a2[i]);
        return 0;
    }
  • 相关阅读:
    SignalR学习笔记(一) 简单聊天室
    纽约工作日志流水账 Day 2
    纽约工作日志流水账 Day 1
    开放计算平台——数据仓库(Hive)权限控制
    SQL Standard Based Hive Authorization(基于SQL标准的Hive授权)
    jmap(Memory Map For Java)
    Hadoop CombineFileInputFormat实现原理及源码分析
    HiveServer连接优化
    Hive SQL运行状态监控(HiveSQLMonitor)
    jstack(Stack Trace for Java)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10294917.html
Copyright © 2011-2022 走看看