看上去很难维护,考虑找一些必要条件。首先显然最大值-最小值=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. 三角形div原理(小知识点)

    三角形div其实就是从边框的演变过程 #sider2{ width: 100px; height: 100px; border-top: 30px solid #000; border-right:  ...

  2. CP-ABE ToolKit 安装笔记

    博主论文狗,好久没有来贴博客,最近做实验需要用到属性加密,了解了下CP-ABE,前来记录一下: 网上相关的博文较多,博主看了大部分的,认为下面这两个看完了基本就可以成功安装. 可参见博文: http: ...

  3. 电子商城实录------定义init初始化的方法

    路由方法的设置 //路由方法 private static function dispatch(){ //获取控制器名称(类比:英文单词的后缀) $controller_name=CONTROLLER ...

  4. ccf201703-2 STLlist

    题目:http://118.190.20.162/view.page?gpid=T56 问题描述 体育老师小明要将自己班上的学生按顺序排队.他首先让学生按学号从小到大的顺序排成一排,学号小的排在前面, ...

  5. SEARCH(文字の検索)

    文字列に関する無効命令 以下の各命令は無効であり.4.6 および 6.10 までのリリースとの互換性を確保するためにのみ利用可能となっています.これらの命令が古いプログラムの中に出現することはあります ...

  6. struts2官方 中文教程 系列七:消息资源文件

    介绍 在本教程中,我们将探索使用Struts 2消息资源功能(也称为 resource bundles 资源绑定).消息资源提供了一种简单的方法,可以将文本放在一个视图页面中,通过应用程序,创建表单字 ...

  7. Hibernate-ORM:07.Hibernate中的参数绑定

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客会讲解Hibernate中的参数绑定,就是相当于sql语句中的where后面的条件 一,讲解概述: 1 ...

  8. 你真的了解React吗

    https://zhufengzhufeng.github.io/zhufengreact/index.html#t21.%E4%BB%80%E4%B9%88%E6%98%AFReact?

  9. 【vim环境配置】解决ubuntu上 由YouCompleteMe插件配置不当引起的 自动补全失效的问题

    背景: 由于不可抗拒的原因,学习环境由之前centos的一台机器上,变成了ubuntu的一台机器上.因此,需要在新的ubuntu的机器上再配置一次vim环境.算起来这已经是第三次配置vim环境了(ma ...

  10. 多个Target的使用

    背景介绍 开发过程中,我们会在内网搭建一个测试服务器,开发.测试都是在内网进行的.这样产生脏数据不会影响外网的服务器.外网服务器只有最后发布时才会进行一些必要的测试. 还有就是要对同一份代码生成不同的 ...