zoukankan      html  css  js  c++  java
  • SDUTOJ1755 装备合成(dfs序+线段树)

    题目描述

    小白很喜欢玩儿LOL,但是无奈自己是个坑货,特别是在装备的选择和合成上,总是站在泉水里为选装备而浪费时间。现在小白试图解决这个问题,为了使问题简单化,我们把游戏中的装备合成规则简化如下:
    (1)装备的合成关系构成一棵合成关系树,如图(a)所示,装备的下级装备叫合成小件,直接连接的叫直接合成小件;上级装备叫合成件,直接连接的叫直接合成件。合成树上的每件装备都可以直接购买,如果钱不够也可以先购买这个装备的合成小件。
    (2)每个装备都有一个合成价格和一个总价格,装备的总价格=该装备的合成价格+该装备所有直接合成小件的总价格之和(图(a)关系树上面显示的数字就是对应装备的总价格)。
    (3)初始的时候(未拥有装备的任何部分),装备的当前价格等于总价格,当前价格会随着购买的小件而发生相应的变化。
    (4)如果购买了某个装备,那么它所有上级可合成装备的当前价格都会相应地减少,减少的量等于这个装备的当前价格。
    (5)如果购买了某个装备,那么它下级所有合成小件都会被购买,也就是说,这些小件都变成已拥有的状态,但是物品栏里只有最终合成的装备,因为是小件合成了这件装备。
    (6)我们认为关系树上的每个装备的直接合成小件都不超过2件,关系树上同一件物品只会出现一次,我们也不考虑物品的出售问题,我们假设物品栏容量无限,金钱无限。
    现在问题来了,按照格式给定一棵合成关系树,再给定一系列操作,完成相应的查询,具体格式见输入。

    输入

    多组输入,对于每组数据:
    第一行有两个整数n m,分别代表关系树中物品的数量和后续的操作数。(1 <= n,m <= 10^4)
    接下来的n行,每行对应一件物品的描述,格式为equipment p k,分别代表装备的名称,合成价格,直接合成小件的个数,然后有k个合成小件的名称synthesis1 synthesis2 ... synthesisk。(1 <= p <=10^4 , k <= 2 , 所有物品名称只包含小写英文字母,长度不超过20)
    接下来的m行,每行对应一个操作,格式如下:
    (1)B equipment ,表示物品equipment被购买。
    (2)Q equipment ,表示要查询物品equipment的当前价格。
    其中equipment代表物品的名称,保证合法且存在于合成关系树中。
    注意:如果B指令购买的装备是当前已经拥有的装备(包括小件),那么忽略该条B购买指令。特别地,如果你已经拥有某件装备,那么查询该物品的当前价格时应该输出这件物品的总价格而不是0

    输出

    对于每次Q查询指令,输出一个整数,代表查询的物品的当前价格。

    示例输入

    8 10
    bannerofcommand 600 2 aegisofthelegion fiendishcodex
    aegisofthelegion 400 2 nullmagicmantle crystallinebracer
    fiendishcodex 465 1 amplifyingtome
    nullmagicmantle 450 0
    crystallinebracer 100 2 rubycrystal rejuvenationbead
    amplifyingtome 435 0
    rubycrystal 400 0
    rejuvenationbead 150 0
    B crystallinebracer
    Q fiendishcodex
    Q bannerofcommand
    B nullmagicmantle
    Q aegisofthelegion
    B aegisofthelegion
    Q bannerofcommand
    Q crystallinebracer
    B bannerofcommand
    Q bannerofcommand

    示例输出

    900
    2350
    400
    1500
    650
    3000

    思路:
    这题很难写,用了dfs序搞出每件装备的范围建线段树,然后线段树实现区间赋0,记录区间和
    购买一件装备时把他管辖的区间全都标记为拥有,然后区间赋0,向上更新(不用向下管了,不会查询到的)
    预处理每件装备的总钱数
    然后查询时如果装备已经拥有,就输出预处理得到的总钱数,如果没有则区间查询它所管辖的区间
    970ms险过。。
    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/31 10:58:16
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int N=10010;
    int n,m,r,ys[N],tree[N<<2];
    map<string,int>mp;
    string s;
    bool ru[N];
    struct wq
    {
        bool f;
        int v;
        int sum;
        int l,r;
    }u[N];
    vector<int>eg[N];
    void dfs(int x)
    {
        u[x].l=++r;
        int ans=u[x].v;
        ys[r]=x;
        for(int i=0;i<eg[x].size();i++)
        {
            dfs(eg[x][i]);
            ans+=u[eg[x][i]].sum;
        }
        u[x].r=r;
        u[x].sum=ans;
    }
    void build(int node,int l,int r)
    {
        if(l==r)
        {
            tree[node]=u[ys[l]].v;
            return ;
        }
        int m=(l+r)>>1;
        build(node<<1,l,m);
        build(node<<1|1,m+1,r);
        tree[node]=tree[node<<1]+tree[node<<1|1];
    }
    void update(int node,int l,int r,int L,int R)
    {
        if(l>=L&&r<=R)
        {
            tree[node]=0;
            return ;
        }
        int m=(l+r)>>1;
        if(m>=L) update(node<<1,l,m,L,R);
        if(m<R) update(node<<1|1,m+1,r,L,R);
        tree[node]=tree[node<<1]+tree[node<<1|1];
    }
    int query(int node,int l,int r,int L,int R)
    {
        if(l>=L&&r<=R) return tree[node];
        int m=(l+r)>>1,ans=0;
        if(m>=L) ans+=query(node<<1,l,m,L,R);
        if(m<R) ans+=query(node<<1|1,m+1,r,L,R);
        return ans;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&m))
        {
            mp.clear();
            r=0;
            memset(ru,0,sizeof(ru));
            for(int i=1;i<=n;i++)
                eg[i].clear();
            int cnt=0,k;
            for(int i=0;i<n;i++)
            {
                cin>>s;
                if(mp.find(s)==mp.end()) mp[s]=++cnt;
                int p=mp[s];
                u[p].f=0;
                scanf("%d",&u[p].v);
                scanf("%d",&k);
                while(k--)
                {
                    cin>>s;
                    if(mp.find(s)==mp.end()) mp[s]=++cnt;
                    eg[p].push_back(mp[s]);
                    ru[mp[s]]=1;
                }
            }
            for(int i=1;i<=n;i++)
                if(!ru[i])
                    dfs(i);
            build(1,1,n);
            char str[2];
            while(m--)
            {
                scanf("%s",str);
                cin>>s;
                int p=mp[s];
                if(str[0]=='B')
                {
                    if(u[u[p].l].f) continue;
                    for(int i=u[p].l;i<=u[p].r;i++)
                        u[i].f=1;
                    update(1,1,n,u[p].l,u[p].r);
                }
                else
                {
                    if(u[u[p].l].f) printf("%d
    ",u[p].sum);
                    else printf("%d
    ",query(1,1,n,u[p].l,u[p].r));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Lost connection to MySQL server at 'waiting for initial communication packet', system error: 0
    Can't connect to MySQL server on '192.168.7.175' (10060)
    单精度浮点数(float)加法计算出错
    当前不会命中断点 还没有为该文档加载任何符号
    64位程序,long*转long 出错
    当前安全设置不允许下载该文件的原因以及图文解决办法
    IndentationError: unindent does not match any outer indentation level
    MongoDB状态查询:db.serverStatus()
    bson.errors.InvalidStringData: strings in documents must be valid UTF-8
    Transformer的PyTorch实现
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5545154.html
Copyright © 2011-2022 走看看