ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

2022/1/25-2022牛客寒假算法基础集训营1B-炸鸡块君与FIFA22(线段树)

2022-01-25 19:04:50  阅读:124  来源: 互联网

标签:25 10 int tr cin else 2022 排位 集训营


题目描述

热爱足球(仅限游戏)的炸鸡块君最近购买了FIFA22,并且沉迷于FIFA22的Rivals排位上分。

在该排位系统中,每局游戏可能有胜利(用W表示)、失败(用L表示)、平局(用D表示)三种结果,胜利将使得排位分加一、失败使排位分减一、平局使排位分不变。特别地,该排位系统有着存档点机制,其可以简化的描述为:若你当前的排位分是3的整倍数(包括0倍),则若下一局游戏失败,你的排位分将不变(而不是减一)。

现在,给定一个游戏结果字符串和若干次询问,你需要回答这些询问。

每次询问格式为(l,r,s),询问若你初始有ss分,按从左到右的顺序经历了[l,r]这一子串的游戏结果后,最终分数是多少。

输入样例
10 7
WLDLWWLLLD
2 6 0
2 6 1
2 6 2
2 6 9
1 7 0
7 10 10
10 10 100
输出样例
2
2
2
11
1
9
100

分析

首先这种2e5的区间查询很容易就想到线段树了,想了一会果然能解。因为题意要求能整除3的时候负不扣分,我们可以分情况讨论进而用线段树维护区间对答案的总贡献,我们设c[i]表示初始值%3后为i的时候选择这一区间后答案的增加量。那初始化很简单对吧这三种状态赢贡献都是1,平都是0,负的话只有0的时候是0其余都是-1
if (s[l] == 'W')
        {
            tr[u].c[0] = 1;
            tr[u].c[1] = 1;
            tr[u].c[2] = 1;
        }
        else if (s[l] == 'L')
        {
            tr[u].c[0] = 0;
            tr[u].c[1] = -1;
            tr[u].c[2] = -1;
        }
        else
        {
            tr[u].c[0] = 0;
            tr[u].c[1] = 0;
            tr[u].c[2] = 0;
        }
然后考虑up操作,我们和上面一样分情况讨论,[l,r]区间初始为i的贡献=左区间为i的贡献+右区间初始值为(i+右区间)%3的贡献。
void pushup(int u)
{
    for (int i = 0; i < 3; i++)
    {
        tr[u].c[i] = max(tr[u << 1].c[i] + tr[u << 1 | 1].c[(i + tr[u << 1].c[i])%3], -i);
    }
}
至此此题结束。

C++代码

/*made in dirt & sand */
#include <bits/stdc++.h>
#define endl '\n'
#define bug(a) cout << a << endl
#define bug2(a, b) cout << (a) << ' ' << (b) << endl
#define bug3(a, b, c) cout << (a) << ' ' << (b) << ' ' << (c) << endl
#define pb push_back
//#define int long long
#define x first
#define y second
#define pii pair<int, int>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int i, j,  n, m, x,y;
int a[N];
char s[N];
struct node
{
    int l, r;
    int c[3];
} tr[N<<2];

void pushup(int u)
{
    for (int i = 0; i < 3; i++)
    {
        tr[u].c[i] = max(tr[u << 1].c[i] + tr[u << 1 | 1].c[(i + tr[u << 1].c[i])%3], -i);
    }
}

void build(int u, int l, int r)
{
    tr[u] = {l, r};
    if (l == r)
    {
        if (s[l] == 'W')
        {
            tr[u].c[0] = 1;
            tr[u].c[1] = 1;
            tr[u].c[2] = 1;
        }
        else if (s[l] == 'L')
        {
            tr[u].c[0] = 0;
            tr[u].c[1] = -1;
            tr[u].c[2] = -1;
        }
        else
        {
            tr[u].c[0] = 0;
            tr[u].c[1] = 0;
            tr[u].c[2] = 0;
        }
    }
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

ll query(int u, int l, int r, int q)
{
    if (tr[u].l >= l && tr[u].r <= r)
    {
        return tr[u].c[q];
    }
    int mid = tr[u].l + tr[u].r >> 1;
    ll sum = 0;
    if (l <= mid)
        sum = query(u << 1, l, min(mid, r), q);
    if (r > mid)
        sum += query(u << 1 | 1, max(mid + 1, l), r, (q + sum) % 3);
    return sum;
}

signed main()
{
    // freopen("black.in","r",stdin);
    //std::ios::sync_with_stdio(false);
    //cin.tie(0);
    int T = 0;
    cin >> n >> m;
    cin >> (s + 1);
    build(1, 1, n);
    while (m--)
    {
        int z;
        cin >> x >> y >> z;
        cout << z  + query(1, x, y, z % 3) << endl;
        ;
    }
}

标签:25,10,int,tr,cin,else,2022,排位,集训营
来源: https://blog.csdn.net/weixin_55630352/article/details/122690398

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有