B - Bezas Hangover Gym - 102448B(線段樹)

Friday nights are tricky for UFPE’s ICPC competitors - they must be careful with their plans, after all, they train on saturdays and must be in good shape to help their team. Beza, however, went to a party on his friday night and said that no booze could bring him down. He was wrong.

Beza’s night had N hours, the party’s bar had M distinct beverages and, at each of the N hours, Beza went to the bar and got one of the M drinks. Lucas, who is an experienced drinker, said that a competitor would not be hungover the next day if the total volume of alcohol he drank did not exceed half the number of minutes he spent drinking.

Saturday morning, Beza woke up and noticed he was terribly hungover, and this made him think about the things he did on that night. Since Beza has got a nasty headache, he’s not able to think clearly, and, therefore, asks you to help him answer some questions he has about that night.

Beza’s questions can be of two types:

1 X Y - he wonders if it would be a good idea to drink Y at the X-th hour. Therefore, he changes the beverage of the X-th hour to Y. It is guaranteed that the beverage Y was available at the bar. (1≤X≤N)
2 L R - he asks himself if he would be hungover on saturday, if his night only consisted of drinking from the L-th to the R-th hour, given his night’s “drink schedule” at the moment of this query. (1≤L≤R≤N)
Input
The first line of input consists of three integers N, M, and Q, (1≤N,M,Q≤2⋅105). The next line contains N strings Di, 1≤|Di|≤20, each one describing the name of the i-th drink Beza had that night. Then, M lines follow, each one containing two entries S and V, 1≤|S|≤20, 1≤V≤100, which describe, respectively, the name of a drink the bar had and how many liters of alcohol it had. Finally, Q lines follow, each one containing three integers, as described on the problem’s statement.

Output
For all queries of type 2, you must answer “YES” if Beza would be hungover the next day, given the interval of hours on which he would be drinking, and “NO” otherwise. It is guaranteed that there will be at least one query of type 2.

Example
Input
6 6 5
vodka pitu beats whisky vodka cuba
vodka 30
caipirinha 10
pitu 35
beats 15
whisky 20
cuba 50
2 3 4
1 3 cuba
2 3 3
1 5 cuba
2 1 5
Output
NO
YES
YES
Note
The total amount of hours passed by on a given interval [L,R] is R−L+1.

題意:
單點修改和區間求和。
問區間和是否大於區間時間值的一半

思路:
很裸的線段樹題。
但是我和隊友都犯了很sb的錯誤——map只存了一開始輸入的n個字符串,而不是後面的m個字符串。因爲前面的n個字符不一定包含了所有種類。

#include <cstdio>
#include <map>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
 
typedef long long ll;
const int maxn = 2e5 + 7;
string s;
string str[maxn];
map<string,int>mp;
int a[maxn];
 
struct Tree {
    int l,r;
    int sum;
}t[maxn << 2];
 
void pushup(int i) {
    t[i].sum = t[i * 2].sum + t[i * 2 + 1].sum;
}
 
void build(int i,int l,int r) {
    t[i].l = l;t[i].r = r;
    if(l == r) {
        t[i].sum = a[mp[str[l]]];
        return;
    }
    int m = (l + r) >> 1;
    build(i * 2,l,m);
    build(i * 2 + 1,m + 1,r);
    pushup(i);
}
 
void update(int i,int x,int v) {
    if(t[i].l == t[i].r) {
        t[i].sum = v;
        return;
    }
    int m = (t[i].l + t[i].r) >> 1;
    if(x <= m) update(i * 2,x,v);
    else update(i * 2 + 1,x,v);
    pushup(i);
}
 
int query(int i,int x,int y) {
    if(x <= t[i].l && t[i].r <= y) {
        return t[i].sum;
    }
    int m = (t[i].l + t[i].r) >> 1;
    int res = 0;
    if(x <= m) res += query(i * 2,x,y);
    if(y > m) res += query(i * 2 + 1,x,y);
    return res;
}
 
 
int main() {
    int n,m,q;scanf("%d%d%d",&n,&m,&q);
    int cnt = 0;
    for(int i = 1;i <= n;i++) {
        cin >> str[i];
    }
    for(int i = 1;i <= m;i++) {
        cin >> s;
        mp[s] = i;
        int x;scanf("%d",&x);
        a[i] = x;
    }
 
    
    build(1,1,n);
    for(int i = 1;i <= q;i++) {
        int op;scanf("%d",&op);
        if(op == 1) {
            int x;scanf("%d",&x);
            cin >> s;
            int y = a[mp[s]];
            update(1,x,y);
        }
        else {
            int x,y;scanf("%d%d",&x,&y);
            int num = query(1,x,y);
            if(num > 30 * (y - x + 1)) {
                printf("YES\n");
            } else {
                printf("NO\n");
            }
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章