更好的阅读体验

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;
}

最新文章

  1. Html-浅谈如何正确给table加边框
  2. Set和存储顺序
  3. 配置Maven环境并创建简单的web项目步骤
  4. jquery内容选择器(匹配内容不为空的元素)
  5. 仿知乎/途家导航栏渐变文字动画效果-b
  6. linux下libreoffice安装测试
  7. eclipse 工具栏修改
  8. c语言中,有符号数位移
  9. 第23篇 js快速学习知识
  10. Spring框架学习1
  11. Vijos 1007 绕钉子的长绳子
  12. 【搬运工】之——Selenium+IDEA+Maven+TestNG环境搭建(转)
  13. 【vue】vue +element 搭建项目,点击空白处关闭弹窗
  14. 【CH5105】cookies 贪心+DP
  15. 简单的Git流程
  16. Elasticsearch 节点角色说明
  17. 快速排序 C语言实现
  18. 【sping揭秘】2、关于spring配置文件
  19. 1-100求和 sum(range(101))
  20. oracle统计字符串包含字符个数

热门文章

  1. python编程基础之六
  2. 8 个 Python 实用脚本,【速】收藏备用!
  3. C--二分搜索
  4. Centos7安装及配置DHCP服务
  5. 2. SOFAJRaft源码分析—JRaft的定时任务调度器是怎么做的?
  6. 算法学习之剑指offer(十)
  7. VirtualBox for Mac 6.0.14 开源免费虚拟机方案
  8. 上传漏洞之常见MIME类型
  9. 基于powershell的socks代理
  10. opencv::处理边缘