URAL 1650. Billionaires(线段树)

题意:求城市财富排行第一的天数。有两个城市的财富值都最多,则不计算。

首先输入n行,每行代表一个人。 名字,最初所在的城市,拥有的财富(不一定能被100000000整除)。

计算m天的城市财富排行。这些人有k次迁移。

k行,每一行分别是:在第几天晚上迁移的,迁移的人,迁入的城市。

用线段树记录每一个城市的财富值、

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <string>

#define LL long long
#define DB double
#define SI(a) scanf("%d",&a)
#define SD(a) scanf("%lf",&a)
#define SS(a) scanf("%s",a)
#define SF scanf
#define PF printf
#define MM(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int (i)=(a);(i)<(b);(i)++)
#define N 100009
#define INF 0x3f3f3f3f
#define EPS 1e-8
#define bug puts("bug")
using namespace std;
map<string,int> city;
map<string,int> peop;
struct nod{
    char ch[2][29];
    LL k;
} re1[N],re2[N];
int n,m,d;
LL money[N];
int sum[N];
char where[N][29];
string recity[N];
struct TR{
    LL mx;int two,p;
} tree[N<<2];
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
void update(int rt)
{
    int l=rt<<1,r=rt<<1|1;
    if(tree[l].mx>tree[r].mx)
    {
        tree[rt] = tree[l];
    }else if(tree[l].mx<tree[r].mx)
    {
        tree[rt] = tree[r];
    }else
    {
        tree[rt].mx = tree[l].mx;
        tree[rt].two = 1;
        tree[rt].p = -1;
    }
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].mx = 0;
        tree[rt].two = 0;
        tree[rt].p = l;
        return ;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    update(rt);
}
void add(int p,LL c,int rt,int l,int r)
{
    if(l==r)
    {
        tree[rt].mx += c;
        tree[rt].two = 0;
        return ;
    }
    int m = (l+r)>>1;
    if(p<=m) add(p,c,lson);
    else add(p,c,rson);
    update(rt);
}
struct AN{
    string cit;
    bool operator<(const AN t)const
    {
        return cit<t.cit;
    }
    int val;
} ans[N];
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    SI(n);
    int cnt = 0;
    REP(i,0,n)
    {
        SS(re1[i].ch[0]);//peop
        SS(re1[i].ch[1]);//city
        LL tm;
        cin>>tm;
        money[i] = re1[i].k = tm;
        peop[string(re1[i].ch[0])]=i;
        recity[cnt] = re1[i].ch[1];
        city[string(re1[i].ch[1])]=cnt++;
        memcpy(where[i],re1[i].ch[1],sizeof(re1[i].ch[1]));
    }
    SI(d);SI(m);
    REP(i,0,m)
    {
        cin>>re2[i].k;
        SS(re2[i].ch[0]);//name
        SS(re2[i].ch[1]);//city
        if(city.find(re2[i].ch[1])==city.end())
        {
            recity[cnt] = re2[i].ch[1];
            city[string(re2[i].ch[1])] = cnt++;
        }
    }
    build(1,0,cnt-1);
    REP(i,0,n){
        add(city[re1[i].ch[1]],money[i],1,0,cnt-1);
    }
    int dy = 0;
    REP(i,0,m)
    {
        int tmp = re2[i].k - dy;
        dy = re2[i].k;
        if(tree[1].two==0)
        {
            sum[tree[1].p] += tmp;
        }
        int who = peop[string(re2[i].ch[0])];
        add(city[string(where[who])],0-money[who],1,0,cnt-1);
        add(city[string(re2[i].ch[1])],money[who],1,0,cnt-1);
        strcpy(where[who],re2[i].ch[1]);
    }
    if(tree[1].two==0)
    {
        sum[tree[1].p] += d-dy;
    }
    int an = 0;
    REP(i,0,cnt)
    {
        if(sum[i]>0)
        {
            ans[an].cit = recity[i];
            ans[an].val = sum[i];
            an++;
        }
    }
    sort(ans,ans+an);
    REP(i,0,an)
    {
        cout<<ans[i].cit<<" "<<ans[i].val<<endl;
    }
    return 0;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值