看上去很难维护,考虑找一些必要条件。首先显然最大值-最小值=k*(r-l)。然后区间内的数需要模k同余。最后区间内的数两两不同(k=0除外)。冷静一下可以发现这些条件组合起来就是充分的了。

  考虑怎么维护。最大值最小值非常简单。模k同余相当于区间内相邻两数的差都是k的倍数,可以维护差分数组的gcd。两两不同相当于区间内没有出现次数>1的数,对每个数用set维护上一个和他相同的数的位置,线段树维护,区间查询max,如果<l则说明不存在。

  开始判断是否不同的写出锅了,结果删掉竟然过了23333

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<cassert>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 300010
#define ll long long
int n,m,a[N],b[N],lst,cnt;
map<int,int> f;
set<int> pre[N<<];
int L[N<<],R[N<<],mn[N<<],mx[N<<],GCD[N<<],last[N<<];
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
void up(int k)
{
mn[k]=min(mn[k<<],mn[k<<|]);
mx[k]=max(mx[k<<],mx[k<<|]);
last[k]=max(last[k<<],last[k<<|]);
GCD[k]=gcd(GCD[k<<],GCD[k<<|]);
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;
if (l==r)
{
mn[k]=mx[k]=a[l];GCD[k]=b[l];
last[k]=*(--pre[f[a[l]]].find(l));
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
up(k);
}
void modify(int k,int p,int x,int op)
{
if (L[k]==R[k])
{
if (op==) mn[k]=mx[k]=x;
else if (op==) GCD[k]=x;
else last[k]=x;
return;
}
int mid=L[k]+R[k]>>;
if (p<=mid) modify(k<<,p,x,op);
else modify(k<<|,p,x,op);
up(k);
}
int qmax(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return mx[k];
int mid=L[k]+R[k]>>;
if (r<=mid) return qmax(k<<,l,r);
else if (l>mid) return qmax(k<<|,l,r);
else return max(qmax(k<<,l,mid),qmax(k<<|,mid+,r));
}
int qmin(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return mn[k];
int mid=L[k]+R[k]>>;
if (r<=mid) return qmin(k<<,l,r);
else if (l>mid) return qmin(k<<|,l,r);
else return min(qmin(k<<,l,mid),qmin(k<<|,mid+,r));
}
int qgcd(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return GCD[k];
int mid=L[k]+R[k]>>;
if (r<=mid) return qgcd(k<<,l,r);
else if (l>mid) return qgcd(k<<|,l,r);
else return gcd(qgcd(k<<,l,mid),qgcd(k<<|,mid+,r));
}
int qlast(int k,int l,int r)
{
if (L[k]==l&&R[k]==r) return last[k];
int mid=L[k]+R[k]>>;
if (r<=mid) return qlast(k<<,l,r);
else if (l>mid) return qlast(k<<|,l,r);
else return max(qlast(k<<,l,mid),qlast(k<<|,mid+,r));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("bzoj4373.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=;i<=n;i++)
{
a[i]=read(),b[i]=abs(a[i]-a[i-]);
if (f.find(a[i])==f.end()) f[a[i]]=++cnt,pre[cnt].insert();
pre[f[a[i]]].insert(i);
}
build(,,n);
while (m--)
{
int op=read();
if (op==)
{
int p=read()^lst,x=read()^lst;
int t=f[a[p]];set<int>::iterator it=++pre[t].find(p);
if (it!=pre[t].end()) modify(,*it,*(--pre[t].find(p)),);
pre[t].erase(p);
a[p]=x;modify(,p,x,);
modify(,p,abs(a[p]-a[p-]),);
if (p<=n) modify(,p+,abs(a[p+]-a[p]),);
if (f.find(a[p])==f.end()) f[a[p]]=++cnt,pre[cnt].insert();
t=f[a[p]];it=pre[t].lower_bound(p);
if (it!=pre[t].end()) modify(,*it,p,);
it--;modify(,p,*it,);pre[t].insert(p);
}
else
{
int l=read()^lst,r=read()^lst,d=read()^lst;
if (qmax(,l,r)-qmin(,l,r)==1ll*d*(r-l)&&(d==||l==r||((qgcd(,l+,r)%d==)&&qlast(,l,r)<l))) lst++,printf("Yes\n");
else printf("No\n");
}
}
return ;
}

BZOJ4373 算术天才⑨与等差数列(线段树)的更多相关文章

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

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

  2. bzoj4373 算术天才⑨与等差数列——线段树+set

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 一个区间有以 k 为公差的数列,有3个条件: 1.区间 mx - mn = (r-l) ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. vue组件的基本知识点

    1. 组件中 is 的特性: 有些 HTML 元素,诸如 <ul>.<ol>.<table> 和 <select>,对于哪些元素可以出现在其内部是有严格 ...

  2. Angular-chart.js 使用说明(基于angular.js工程)

    Angular-chart.js是基于Chart.js的angular组件,引入项目后直接操作数据即可. 引用方法:    分别将Chart.js.angular-chart.js.angular-c ...

  3. webpack 4.14配置详解

    1.安装nodejs 官网下载nodejs,安装时可能会爆 2503错误,解决办法是:使用管理员命令执行安装文件.cmd ->命令提示符(管理员)-> 输入: msiexec /packa ...

  4. BootCDNApi使用记录

    通过API获取BootCDN所加速的所有前端开源库的基本信息和文件列表 API 将一下API链接中的.min字样去掉后,获取到的JSON格式的返回信息是经过良好的格式化的,便于查看. 所有开源库简要信 ...

  5. Kuernetes-设计架构(二)

    Kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs,scheduler.etc),一切都基于分布式的存储系统.Kubernetes架构图: ...

  6. R语言学习笔记(三):零碎知识点(1-10)

    1--c() c表示"连接"(concatenate). 在R中向量是连续存储的,因此不能插入或删除元素. 2--seq() seq()的特殊用法,可以用在for循环里for(i ...

  7. ABAP CDS ON HANA-(12)ODATA Service

    Create a CDS view and we have the view type as ‘BASIC’ view To publish this as oData, add the annota ...

  8. Moodle 3.4中添加小组、大组、群

    Moodle在高中应用时经常要用到年级.班级和小组,我们可以用群.大组.小组来代替. 小组设置:网站首页-->现有课程-->右上角的设置按钮-->更多-->用户-->小组 ...

  9. 10 TCP 传输控制协议 UDP区别

    1.tcp和udp区别 2.TCP通信模型 生活中的电话机 如果想让别人能更够打通咱们的电话获取相应服务的话,需要做一下几件事情: 买个手机 插上手机卡 设计手机为正常接听状态(即能够响铃) 静静的等 ...

  10. NB-IOT的键值对

    1. 关于NB-IOT的软件开发,有一个功能,NB收到数据的时候可以唤醒处于低功耗下的MCU. 2. 2个键值对可以配置这个功能.使用键值对的方式. 3. 遇到的第一个问题,<config> ...