题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373

一个区间有以 k 为公差的数列,有3个条件:

1.区间 mx - mn = (r-l) * k;

2.差分数组的 gcd 是 k 的倍数;

3.没有重复出现的数;

其中1,2都可以用线段树维护,3用 set 维护每个数上一个出现的位置即可;

模仿TJ写的:https://blog.csdn.net/neither_nor/article/details/52461940

对 set 更熟悉了,细节还蛮多的。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
using namespace std;
int const maxn=3e5+;
int n,m,a[maxn],key,tot,pre[maxn];
map<int,int>h;
set<int>s[maxn<<];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int ab(int x){return x>?x:-x;}
struct N{
int mx,mn,fro,g;
friend N operator + (N x,N y)
{
N ret;
ret.mx=max(x.mx,y.mx);
ret.mn=min(x.mn,y.mn);
ret.fro=max(x.fro,y.fro);
ret.g=gcd(x.g,y.g);
return ret;//!
}
}t[maxn<<];
void build(int x,int l,int r)
{
if(l==r)
{
t[x].mn=t[x].mx=a[l]; t[x].g=ab(a[l+]-a[l]);
t[x].fro=pre[l]; return;
}
int mid=((l+r)>>);
build(x<<,l,mid); build(x<<|,mid+,r);
t[x]=t[x<<]+t[x<<|];
}
void update(int x,int l,int r,int p)
{
if(l==r)
{
t[x].mn=t[x].mx=a[l]; t[x].g=ab(a[l+]-a[l]);
t[x].fro=pre[l]; return;
}
int mid=((l+r)>>);
if(p<=mid)update(x<<,l,mid,p);
else update(x<<|,mid+,r,p);
t[x]=t[x<<]+t[x<<|];
}
N query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R)return t[x];
int mid=((l+r)>>);
if(mid<L)return query(x<<|,mid+,r,L,R);
else if(mid>=R)return query(x<<,l,mid,L,R);
else return query(x<<,l,mid,L,R)+query(x<<|,mid+,r,L,R);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(!h[a[i]])
{
h[a[i]]=++tot;
s[tot].insert();
s[tot].insert(n+);
}
int tmp=h[a[i]];
s[tmp].insert(i);
pre[i]=*--(s[tmp].insert(i).first);//
}
a[n+]=a[n];//!
build(,,n);
for(int i=,op,x,y,l,r,k;i<=m;i++)
{
scanf("%d",&op);
if(op==)
{
scanf("%d%d",&x,&y);
x^=key; y^=key;
int tmp,nxt,pr;
tmp=h[a[x]];
nxt=*s[tmp].upper_bound(x);
if(nxt!=n+)
{
pre[nxt]=pre[x];
update(,,n,nxt);
}
s[tmp].erase(x); if(!h[y])//
{
h[y]=++tot;
s[tot].insert();
s[tot].insert(n+);
}
tmp=h[y];
s[tmp].insert(x);
nxt=*s[tmp].upper_bound(x);
pre[x]=*--s[tmp].lower_bound(x);
if(nxt!=n+)
{
pre[nxt]=x;
update(,,n,nxt);
}
a[x]=y;
update(,,n,x);
if(x!=)update(,,n,x-);//
}
if(op==)
{
scanf("%d%d%d",&l,&r,&k);
l^=key; r^=key; k^=key;
if(l==r){key++; printf("Yes\n"); continue;}
N tmpp=query(,,n,l,r-);//
N tmp=tmpp+query(,,n,r,r);//
if(k==)
{
if(tmp.mx==tmp.mn)key++,printf("Yes\n");
else printf("No\n");
continue;
}
if(tmp.fro<l && tmp.mx==k*(r-l)+tmp.mn && tmpp.g%k==)//tmpp!
key++,printf("Yes\n");
else printf("No\n");
}
}
return ;
}

bzoj4373 算术天才⑨与等差数列——线段树+set的更多相关文章

  1. [BZOJ4373]算术天才⑨与等差数列(线段树)

    [l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...

  2. BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)

    题意 题目链接 Sol 正经做法不会,听lxl讲了一种很神奇的方法 我们考虑如果满足条件,那么需要具备什么条件 设mx为询问区间最大值,mn为询问区间最小值 mx - mn = (r - l) * k ...

  3. 【BZOJ4373】算术天才⑨与等差数列 线段树+set

    [BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...

  4. 【BZOJ4373】算术天才⑨与等差数列 [线段树]

    算术天才⑨与等差数列 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 算术天才⑨非常喜欢和等 ...

  5. BZOJ 4373 算术天才⑨与等差数列 线段树+set(恶心死我了)

    mdzz,这道题重构了4遍,花了一个晚上... 满足等差数列的条件: 1. 假设min是区间最小值,max是区间最大值,那么 max-min+k(r−l) 2. 区间相邻两个数之差的绝对值的gcd=k ...

  6. BZOJ 4373算术天才⑨与等差数列(线段树)

    题意:给你一个长度为n的序列,有m个操作,写一个程序支持以下两个操作: 1. 修改一个值 2. 给出三个数l,r,k, 询问:如果把区间[l,r]的数从小到大排序,能否形成公差为k的等差数列. n,m ...

  7. BZOJ 4373: 算术天才⑨与等差数列 线段树

    Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能 ...

  8. bzoj 4373 算术天才⑨与等差数列——线段树+set

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 能形成公差为k的等差数列的条件:mx-mn=k*(r-l) && 差分 ...

  9. BZOJ4373 算术天才⑨与等差数列 【线段树】*

    BZOJ4373 算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k ...

随机推荐

  1. asp.net MVC 下拉多级联动及编辑

    多级联动实现,附源码.当前,部分代码是参与博客园其它网友. 新增,前台代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2 ...

  2. 脚本添加删除nginx配置中的内容

    [root@nodejs script]# more editnginx.sh #!/bin/bash # function back_check(){ # 备份配置和覆盖配置文件 cp -rf /e ...

  3. crontab错误处理

    crontab任务跑着跑着突然停了,莫名奇妙,查看日志,发现以下错误: 网上搜了一下报错,提示说是调整打开最大进程数,设置如下

  4. python开发 面试题

    一.简述列表与元组的区别 答: 元组tuple与列表List相同点 元组tuple与列表List都是序列类型的容器对象,可以存放任何类型的数据.支持切片.迭代等操作. 元组tuple与列表List区别 ...

  5. FTP服务器访问主动模式、被动模式

    在公司里面,经常需要访问外网FTP取资料等情况.但是有时用windows界面访问经常遇到各种问题. 下面介绍两种客户端是如何访问ftp服务器. 首先我们需要说明:防火墙,是阻拦外界与内部的通讯的一道关 ...

  6. 如何使用 Python 创建一名可操控的角色玩家

    在 这个系列的第一篇文章 中,我解释了如何使用 Python 创建一个简单的基于文本的骰子游戏.在第二部分中,我向你们展示了如何从头开始构建游戏,即从 创建游戏的环境 开始.但是每个游戏都需要一名玩家 ...

  7. Unity中确定时间是否在一定范围内

    NowTime = DateTime.Now.ToLocalTime(); Timeyear = DateTime.Now.ToLocalTime().ToString("yyyy-MM-d ...

  8. Django REST framework 渲染器、版本

    渲染器.版本: # settings.py REST_FRAMEWORK = { "DEFAULT_RENDERER_CLASSES": [ "rest_framewor ...

  9. redis环境部署

    运维开发技术交流群欢迎大家加入一起学习(QQ:722381733) 一.Redis服务介绍: redis简单来讲就是一个数据库,一个用来存储缓存的数据库容器,主要是让项目数据能写进缓存,为用户提搞更舒 ...

  10. centos 7中 yum安装jdk

    yum安装jdk的好处就是不需要手动再配置环境变量,所有的变量都是自动生成 1.检查系统是否存在jdk,存在删除原版jdk 如果没有信息输出,则表示没有安装jdk rpm -qa |grep java ...