Description

算术天才⑨非常喜欢和等差数列玩耍。
有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。
他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。
当然,他还会不断修改其中的某一项。
为了不被他鄙视,你必须要快速并正确地回答完所有问题。
注意:只有一个数的数列也是等差数列。

Input

第一行包含两个正整数n,m(1<=n,m<=300000),分别表示序列的长度和操作的次数。
第二行包含n个整数,依次表示序列中的每个数a[i](0<=a[i]<=10^9)。
接下来m行,每行一开始为一个数op,
若op=1,则接下来两个整数x,y(1<=x<=n,0<=y<=10^9),表示把a[x]修改为y。
若op=2,则接下来三个整数l,r,k(1<=l<=r<=n,0<=k<=10^9),表示一个询问。
在本题中,x,y,l,r,k都是经过加密的,都需要异或你之前输出的Yes的个数来进行解密。

Output

输出若干行,对于每个询问,如果可以形成等差数列,那么输出Yes,否则输出No。

题解:

公差 $k$ 和区间长度都是固定的,所以等差数列也是唯一确定的.
这里分几个情况:
$l=r$,无限制条件.
$k=0$,所有数必须都相同.
其他情况,令区间最大值为 $Max$,最小值为 $Min$,那么 $Max-Min=(len-1)\times k$
除此之外,还需满足没有数字重复出现,任意两个数的差都是 $k$ 的倍数 
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#define ll long long
using namespace std;
namespace IO {
#define rint register int
void setIO(string s) {
string in=s+".in",out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
inline int read(){
rint x=0,f=1;char ch=getchar();
while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
};
const int maxn=300006;
const int inf=1000000002;
int n,m;
int arr[maxn],brr[maxn];
int GCD(int a,int b) {
return b?GCD(b,a%b):a;
}
namespace A {
int minv[maxn<<2],maxv[maxn<<2];
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
minv[now]=minv[now<<1];
maxv[now]=maxv[now<<1];
if(r>mid) {
minv[now]=min(minv[now],minv[now<<1|1]);
maxv[now]=max(maxv[now],maxv[now<<1|1]);
}
}
void build(int l,int r,int now) {
if(l==r) {
minv[now]=maxv[now]=arr[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p,int v) {
if(l==r) {
minv[now]=maxv[now]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p,v);
else update(mid+1,r,now<<1|1,p,v);
pushup(l,r,now);
}
int qmax(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return maxv[now];
int mid=(l+r)>>1,re=0;
if(mid>=L) re=max(re,qmax(l,mid,now<<1,L,R));
if(R>mid) re=max(re,qmax(mid+1,r,now<<1|1,L,R));
return re;
}
int qmin(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return minv[now];
int mid=(l+r)>>1,re=inf;
if(mid>=L) re=min(re,qmin(l,mid,now<<1,L,R));
if(R>mid) re=min(re,qmin(mid+1,r,now<<1|1,L,R));
return re;
}
};
namespace lst {
int id;
int lst[maxn<<2];
map<int,int>idx;
set<int>S[maxn<<1];
set<int>::iterator it;
void insert(int v,int i) {
if(!idx[v]) idx[v]=++id;
int cur=idx[v];
S[cur].insert(i);
}
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
lst[now]=lst[now<<1];
if(r>mid) lst[now]=max(lst[now],lst[now<<1|1]);
}
void build(int l,int r,int now) {
if(l==r) {
int cur=idx[arr[l]];
it=S[cur].lower_bound(l);
if(it==S[cur].begin()) lst[now]=-inf;
else {
it--;
lst[now]=(*it);
}
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p) {
if(l==r) {
int cur=idx[arr[l]];
it=S[cur].lower_bound(l);
if(it==S[cur].begin()) lst[now]=-inf;
else {
it--;
lst[now]=(*it);
}
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p);
else update(mid+1,r,now<<1|1,p);
pushup(l,r,now);
}
int query(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return lst[now];
int mid=(l+r)>>1,re=0;
if(L<=mid) re=max(re, query(l,mid,now<<1,L,R));
if(R>mid) re=max(re, query(mid+1,r,now<<1|1,L,R));
return re;
}
void modify(int v,int i) {
if(!idx[v]) idx[v]=++id;
int cur=idx[v];
S[idx[arr[i]]].erase(i);
it=S[idx[arr[i]]].lower_bound(i+1);
if(it!=S[idx[arr[i]]].end()) {
update(1,n,1,(*it));
}
S[cur].insert(i), arr[i]=v;
update(1,n,1,i);
}
};
namespace delta {
int gc[maxn<<2];
void pushup(int l,int r,int now) {
int mid=(l+r)>>1;
gc[now]=gc[now<<1];
if(r>mid) gc[now]=GCD(gc[now<<1|1],gc[now]);
}
void build(int l,int r,int now) {
if(l==r) {
gc[now]=brr[l];
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,now<<1);
if(r>mid) build(mid+1,r,now<<1|1);
pushup(l,r,now);
}
void update(int l,int r,int now,int p,int v) {
if(l==r) {
gc[now]=v;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,now<<1,p,v);
else update(mid+1,r,now<<1|1,p,v);
pushup(l,r,now);
}
int query(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R) return gc[now];
int mid=(l+r)>>1,re=0;
if(L<=mid) re=query(l,mid,now<<1,L,R);
if(R>mid) re=re?GCD(re,query(mid+1,r,now<<1|1,L,R)):query(mid+1,r,now<<1|1,L,R);
return re;
}
};
int main() {
using namespace IO;
// IO::setIO("input");
int i,j;
n=read(),m=read();
for(i=1;i<=n;++i) {
arr[i]=read();
lst::insert(arr[i],i);
}
for(i=1;i<=n;++i) brr[i]=abs(arr[i+1]-arr[i]);
A::build(1,n,1);
delta::build(1,n-1,1);
lst::build(1,n,1);
int cc=0;
int h=0;
for(int cas=1;cas<=m;++cas) {
int op=read();
if(op==1) {
int x,y;
x=read(),y=read(),x^=cc,y^=cc;
if(arr[x]==y) continue;
lst::modify(y,x);
A::update(1,n,1,x,y);
if(x==1) delta::update(1,n-1,1,1,abs(arr[2]-arr[1]));
else if(x==n) delta::update(1,n-1,1,n-1,abs(arr[n]-arr[n-1]));
else {
delta::update(1,n-1,1,x-1,abs(arr[x]-arr[x-1]));
delta::update(1,n-1,1,x,abs(arr[x+1]-arr[x]));
}
}
if(op==2) {
int l,r,k;
l=read(),r=read(),k=read();
l^=cc,r^=cc,k^=cc;
if(l==r) printf("Yes\n"),++cc;
else if(k==0) {
if(A::qmin(1,n,1,l,r)==A::qmax(1,n,1,l,r)) printf("Yes\n"),++cc;
else printf("No\n");
}
else {
int len=r-l;
int minn=A::qmin(1,n,1,l,r), maxx=A::qmax(1,n,1,l,r);
int flag=0;
if(maxx-minn==1ll*k*len) {
if(lst::query(1,n,1,l,r)>=l) flag=1;
else {
if(delta::query(1,n-1,1,l,r-1)%k) flag=1;
else {
printf("Yes\n"), ++cc;
}
}
}
else flag=1;
if(flag) printf("No\n");
}
}
}
return 0;
}

  

BZOJ 4373: 算术天才⑨与等差数列 线段树的更多相关文章

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

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

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

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

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

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

  4. bzoj 4373 算术天才⑨与等差数列

    4373: 算术天才⑨与等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem.ph ...

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

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

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

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

  7. bzoj 4373: 算术天才⑨与等差数列 hash

    题目链接 题目大意:  给你n个数, 给两种操作, 一种给你l, r, k,问你[l, r]区间里的数排序后能否构成一个公差为k的等差数列. 另一种是将位置x的数变为y. 强制在线. 可以用hash来 ...

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

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

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

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

随机推荐

  1. jenkins pipline和jenkinsfile

    Jenkins Pipeline(或简称为 "Pipeline")是一套插件,将持续交付的实现和实施集成到 Jenkins 中. Jenkins Pipeline 提供了一套可扩展 ...

  2. []转帖]linux 上修改了nginx.conf 怎么重新加载配置文件生效

    linux 上修改了nginx.conf 怎么重新加载配置文件生效 https://www.cnblogs.com/zhuyeshen/ 步骤如下先利用/usr/local/nginx/sbin/ng ...

  3. 洛谷 P2023 维护序列 题解

    题面 注意一个细节,查询和更新都需要pushdown(); #include <bits/stdc++.h> #define int long long using namespace s ...

  4. Luogu P3647 [APIO2014]连珠线

    题目 换根dp. 显然对于给定的一棵有根树,蓝线都不能拐弯. 设\(f_{u,0}\)表示\(u\)不是蓝线中点时子树内的答案,\(f_{u,1}\)表示\(u\)是蓝线中点时子树内的答案.(以\(1 ...

  5. c++ vector 使用注意事项

    1. 初始化 c++ 11以后新增了大括号{}的初始化方式,需要注意与()的区别,如: std::vector<int> vecTest1(5);         //初始化5个元素,每个 ...

  6. 事件循环(EventLoop)的学习总结

    前言 在学习eventloop之前,我们需要复习一下js的单线程和异步.虽说js是单线程的,但是在浏览器和Node中都做了相应的处理.如浏览器中的web workers(工作线程),Node中的chi ...

  7. 2017年0406------如何使用sessionStroage来储存参数是对象的,以及localStorage和sessionStorage的不同地方

    由于项目需要,需要向另外个页面传参数,,由于参数比较特殊,是对象,所以需要用到sessionStorage方法,下面简单的总结一下方法: (1)这个是要将对象转换成字符串,再存储到storage中, ...

  8. 7.jQuery之显示与隐藏效果

    这里用到三个函数方法:show()   hide()  toggle() 注意点是三个方法里面的两个参数的使用,前一个参数是时间,表示显示速度:后一个参数是回调函数,只有前面的动画执行完之后,回调函数 ...

  9. 使用parted 创建一个大于2T的分区

    1.查看现有分区 parted -l fdisk   -l     2.对/dev/sdb分一个区 [root@test ~]# parted /dev/sdb   (parted) mkpart  ...

  10. yum 安装mysql-server 5.6

    # rpm ivh http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm # yum install -y mysql-s ...