线段树(B - Beza's Hangover )

模板题(区间查询,先修改(用map来存一下酒的毫升))

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 NN hours, the party's bar had MM distinct beverages and, at each of the NN hours, Beza went to the bar and got one of the MM 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:

  • 11 XX YY - he wonders if it would be a good idea to drink YY at the XX-th hour. Therefore, he changes the beverage of the XX-th hour to YY. It is guaranteed that the beverage YY was available at the bar. (1≤X≤N1≤X≤N)
  • 22 LL RR - he asks himself if he would be hungover on saturday, if his night only consisted of drinking from the LL-th to the RR-th hour, given his night's "drink schedule" at the moment of this query. (1≤L≤R≤N1≤L≤R≤N)

Input

The first line of input consists of three integers NN, MM, and QQ, (1≤N,M,Q≤2⋅1051≤N,M,Q≤2⋅105). The next line contains NN strings DiDi, 1≤|Di|≤201≤|Di|≤20, each one describing the name of the ii-th drink Beza had that night. Then, MM lines follow, each one containing two entries SS and VV, 1≤|S|≤201≤|S|≤20, 1≤V≤1001≤V≤100, which describe, respectively, the name of a drink the bar had and how many liters of alcohol it had. Finally, QQ lines follow, each one containing three integers, as described on the problem's statement.

Output

For all queries of type 22, 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 22.

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][L,R] is R−L+1R−L+1.

题意:给出三个数n,m,k,分别代表几个小时喝的什么酒,m代表有m种酒,记录这些酒的容量,k此询问。

当询问的时候,是否在这个时间段内和这些酒这个人是否能醉(如果喝的毫升数小于等于喝酒时间的一半不醉,否则醉)

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn =2e5+100;
int a[maxn];
int tree[maxn*4];
int n,m,k;
map<string,int>mp;
char s[maxn][22];
void build(int l,int r,int node)
{
    if(l==r)
    {
        tree[node]=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,node*2);
    build(mid+1,r,node*2+1);
    tree[node]=tree[node*2]+tree[node*2+1];
}
void updata(int node,int l,int r,int x,int y)
{
    if(l==r)
    {
        tree[node]=y;
        return ;
    }
    int mid=(l+r)/2;
    if(x<=mid)
    {
        updata(node*2,l,mid,x,y);
    }
    if(x>mid)
    {
        updata(node*2+1,mid+1,r,x,y);
    }
    tree[node]=tree[node*2]+tree[node*2+1];
}
int query(int node,int l,int r,int x,int y)
{
    if(l>=x&&r<=y)
    {
        return tree[node];
    }
    int mid=(l+r)/2;
    int res=0;
    if(x<=mid)
    {
        res+=query(node*2,l,mid,x,y);
    }
    if(y>mid)
    {
        res+=query(node*2+1,mid+1,r,x,y);
    }
    return res;
}
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%s",s[i]);
    }
    char str[maxn];
    int x;
    while(m--)
    {
        scanf("%s%d",str,&x);
        mp[str]=x;
//        cout<<mp[str]<<" "<<str<<endl;
    }
    for(int i=1;i<=n;i++)
    {
        a[i]=mp[s[i-1]];
//        cout<<s[i-1]<<" "<<mp[s[i-1]]<<endl;
//        cout<<a[i]<<" "<<s[i-1]<<endl;
    }
//    cout<<endl;
    build(1,n,1);
    int u,v,w;
    while(k--)
    {
        scanf("%d",&u);
        if(u==1)
        {
            scanf("%d",&v);
            scanf("%s",str);
            updata(1,1,n,v,mp[str]);
        }
        else
        {
            scanf("%d%d",&v,&w);
            int ans=query(1,1,n,v,w);
//            printf("%d\n",ans);
            if(ans>(w-v+1)*30) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值