XiaoHuang's Space
XiaoHuang's Space
XiaoHuang
May the force be with you.
「Luogu 3792」由乃与大母神原型和偶像崇拜
Posted: Dec 11, 2019
Last Modified: Dec 13, 2019
This article was last modified days ago. The content of this post may be outdated!

Portal

Portal1: Luogu

Description

给你一个序列$a$

每次两个操作:

  1. 修改$x$位置的值为$y$;

  2. 查询区间$[l, r]$是否可以重排为值域上连续的一段。

Input

第一行两个数$n, m$;

第二行$n$个数表示$a[i]$;

后面m行每行三个数opt x y,或者opt l r,代表操作。

Output

如果可以,输出damushen

否则输出yuanxing

Sample Input

5 5
1 2 3 4 5
2 1 5
2 2 3
2 3 3
1 3 6
2 3 5

Sample Output

damushen
damushen
damushen
damushen

Hint

对于$30\%$的数据,$n, m \le 500$;

对于$60\%$的数据,$n, m \le 100000$;

对于$100\%$的数据,$n, m \le 500000$。

值域$10 ^ 9$;

时限:$2s$

Solution

这题很明显用线段树解决。

题目要求的是更新一个点,查询一个区间是否能够一个等差数列,我们可以线段树维护最小值,最大值以及区间平方和,在查询的时候我们先询问出最小值与最大值,为等差数列的头与尾,那么我们可以算出这个数列的长度,与题目给出的是否一致,不一致就可以输出yuanxing

然后询问线段树的元素的平方和,与计算的头与尾构成的数列的平方和是否一致。

但由于long long自然溢出问题,计算时用暴力解决即可。

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

typedef long long LL;
const int INF = 0x7f7f7f7f, MAXN = 2000005, MAXM = 500005;
int n, m, l, r, opt, a[MAXM];
namespace Segtree {
    #define lc rt << 1
    #define rc rt << 1 | 1
    struct node {
        int Min, Max;
        LL sum;
    } tree[MAXN];
    inline void pushup(int rt) {
        tree[rt].sum = tree[lc].sum + tree[rc].sum;
        tree[rt].Min = min(tree[lc].Min, tree[rc].Min);
        tree[rt].Max = max(tree[lc].Max, tree[rc].Max);
    }
    inline void pushdown(int rt, int val) {
        tree[rt].sum = val * val;
        tree[rt].Min = val;
        tree[rt].Max = val;
    }
    inline void build(int rt, int l, int r) {//建树
        if (l == r) {
            pushdown(rt, a[l]);
            return ;
        }
        int mid = l + r >> 1;
        build(lc, l, mid);
        build(rc, mid + 1, r);
        pushup(rt);
    }
    inline void update(int rt, int l, int r, int pos, int val) {//线段树更改
        if (l == r) {
            pushdown(rt, val);
            return ;
        }
        int mid = l + r >> 1;
        if (pos <= mid) update(lc, l, mid, pos, val); else update(rc, mid + 1, r, pos, val);
        pushup(rt);
    }
    inline int query_min(int rt, int l, int r, int ansl, int ansr) {//线段树询问区间最小值
        if (ansl <= l && r <= ansr) return tree[rt].Min;
        int mid = l + r >> 1, ret = INF;
        if (ansl <= mid) ret = min(ret, query_min(lc, l, mid, ansl, ansr));
        if (mid < ansr) ret = min(ret, query_min(rc, mid + 1, r, ansl, ansr));
        return ret;
    }
    inline int query_max(int rt, int l, int r, int ansl, int ansr) {//线段树询问区间最大值
        if (ansl <= l && r <= ansr) return tree[rt].Max;
        int mid = l + r >> 1, ret = -INF;
        if (ansl <= mid) ret = max(ret, query_max(lc, l, mid, ansl, ansr));
        if (mid < ansr) ret = max(ret, query_max(rc, mid + 1, r, ansl, ansr));
        return ret;
    }
    inline LL query_sum(int rt, int l, int r, int ansl, int ansr) {//线段树询问区间平方和
        if (ansl <= l && r <= ansr) return tree[rt].sum;
        int mid = l + r >> 1;
        LL ret = 0;
        if (ansl <= mid) ret += query_sum(lc, l, mid, ansl, ansr);
        if (mid < ansr) ret += query_sum(rc, mid + 1, r, ansl, ansr);
        return ret;
    }
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    Segtree :: build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        scanf("%d", &opt);
        if (opt == 1) {
            scanf("%d%d", &l, &r);
            Segtree :: update(1, 1, n, l, r);
        } else {
            scanf("%d%d", &l, &r);
            int first = Segtree :: query_min(1, 1, n, l, r), last = Segtree :: query_max(1, 1, n, l, r);
            if (r - l != last - first) {
                printf("yuanxing\n");
                continue;
            }
            LL ans = 0;
            for (int i = first; i <= last; i++)
                ans += (LL)(i * i);
            if (ans == Segtree :: query_sum(1, 1, n, l, r)) printf("damushen\n"); else printf("yuanxing\n");
        }
    }
    return 0;
}
Article License: CC BY-NC-ND 4.0
Article Author: XiaoHuang
  1. 1. Portal
  2. 2. Description
  3. 3. Input
  4. 4. Output
  5. 5. Sample Input
  6. 6. Sample Output
  7. 7. Hint
  8. 8. Solution
  9. 9. Code
Newer Post
『题解』BZOJ2226 [Spoj 5971] LCMSum
Older Post
「CF630C」Lucky Numbers
Buy me a beer?
-->
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×