zoukankan      html  css  js  c++  java
  • 「Luogu 3792」由乃与大母神原型和偶像崇拜

    更好的阅读体验

    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
    ");
                    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
    "); else printf("yuanxing
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SCI写作经典替换词,瞬间高大上!(转)
    最佳化常用测试函数 Optimization Test functions
    算法复杂度速查表
    VS 代码行统计
    CPLEX IDE 菜单栏语言设置( 中文 英文 韩文 等多国语言 设置)
    如何从PDF文件中提取矢量图
    Matlab无法打开M文件的错误( Undefined function or method 'uiopen' for input arguments of type 'char)
    visual studio 资源视图 空白 解决方案
    MFC DialogBar 按钮灰色不响应
    嗨翻C语言笔记(二)
  • 原文地址:https://www.cnblogs.com/shenxiaohuang/p/11574538.html
Copyright © 2011-2022 走看看