[BZOJ4373]算术天才⑨与等差数列(线段树)
[l,r]中所有数排序后能构成公差为k的等差数列,当且仅当:
1.区间中最大数-最小数=k*(r-l)
2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a[l+1],...,a[r]-a[r-1])
3.区间中任意两个数不相同,即设pre[i]为序列中i之前第一个与a[i]相等的数的位置,则max(pre[l],...,pre[r])<l
于是线段树分别维护:区间最大值,区间最小值,区间相邻差的gcd,区间pre的最大值即可。
注意特判下l=r和k=0的情况。
#include<set>
#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (x<<1)
#define rs (ls|1)
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int n,m,tot,op,x,y,l,r,k,w,a[N],d[N],pre[N],Gcd[N<<],mn[N<<],mx[N<<],mxp[N<<];
set<int>S[N<<];
map<int,int>mp; int gcd(int a,int b){ return b ? gcd(b,a%b) : a; } void upd(int x){
mn[x]=min(mn[ls],mn[rs]); mx[x]=max(mx[ls],mx[rs]);
Gcd[x]=gcd(Gcd[ls],Gcd[rs]); mxp[x]=max(mxp[ls],mxp[rs]);
} void build(int x,int L,int R){
if (L==R){ Gcd[x]=d[L]; mn[x]=mx[x]=a[L]; mxp[x]=pre[L]; return; }
int mid=(L+R)>>;
build(lson); build(rson); upd(x);
} void mdf(int x,int L,int R,int pos,int k,int op){
if (L==R){
if (op==) Gcd[x]=k;
if (op==) mn[x]=mx[x]=k;
if (op==) mxp[x]=k;
return;
}
int mid=(L+R)>>;
if (pos<=mid) mdf(lson,pos,k,op); else mdf(rson,pos,k,op);
upd(x);
} int que(int x,int L,int R,int l,int r,int op){
if (L==l && r==R){
if (op==) return Gcd[x];
if (op==) return mn[x];
if (op==) return mx[x];
if (op==) return mxp[x];
}
int mid=(L+R)>>;
if (r<=mid) return que(lson,l,r,op);
else if (l>mid) return que(rson,l,r,op);
else{
if (op==) return gcd(que(lson,l,mid,op),que(rson,mid+,r,op));
if (op==) return min(que(lson,l,mid,op),que(rson,mid+,r,op));
if (op==) return max(que(lson,l,mid,op),que(rson,mid+,r,op));
if (op==) return max(que(lson,l,mid,op),que(rson,mid+,r,op));
}
return ;
} int main(){
freopen("bzoj4373.in","r",stdin);
freopen("bzoj4373.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,n){
scanf("%d",&a[i]),d[i]=abs(a[i]-a[i-]);
if (!mp.count(a[i])){
mp[a[i]]=++tot; pre[i]=; S[tot].insert(i);
}else{
int t=mp[a[i]]; pre[i]=*(--S[t].end()); S[t].insert(i);
}
}
build(,,n);
rep(i,,m){
scanf("%d",&op);
if (op==){
scanf("%d%d",&x,&y); x^=w; y^=w;
if (y==a[x]) continue;
d[x]=abs(y-a[x-]); mdf(,,n,x,d[x],);
if (x<n) d[x+]=abs(a[x+]-y),mdf(,,n,x+,d[x+],);
int t=mp[a[x]]; set<int>::iterator it=S[t].upper_bound(x);
if (it!=S[t].end()) pre[*it]=pre[x],mdf(,,n,*it,pre[*it],); S[t].erase(x);
a[x]=y; mdf(,,n,x,a[x],);
if (!mp.count(a[x])){
mp[a[x]]=++tot; pre[x]=; S[tot].insert(x); mdf(,,n,x,pre[x],);
}else{
int t=mp[a[x]];
set<int>::iterator it=S[t].insert(x).first;
if (it==S[t].begin()) pre[x]=; else pre[x]=*(--it);
mdf(,,n,x,pre[x],);
it=S[t].upper_bound(x);
if (it!=S[t].end()) pre[*it]=x,mdf(,,n,*it,pre[*it],);
}
}else{
scanf("%d%d%d",&l,&r,&k); l^=w; r^=w; k^=w;
if (l==r){ w++; puts("Yes"); continue; }
if (!k){
if (que(,,n,l,r,)==que(,,n,l,r,)) w++,puts("Yes"); else puts("No");
continue;
}
if (que(,,n,l,r,)-que(,,n,l,r,)!=1ll*k*(r-l) || que(,,n,l+,r,)%k || que(,,n,l,r,)>=l) puts("No");
else w++,puts("Yes");
}
}
return ;
}
[BZOJ4373]算术天才⑨与等差数列(线段树)的更多相关文章
- bzoj4373 算术天才⑨与等差数列——线段树+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 一个区间有以 k 为公差的数列,有3个条件: 1.区间 mx - mn = (r-l) ...
- BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)
题意 题目链接 Sol 正经做法不会,听lxl讲了一种很神奇的方法 我们考虑如果满足条件,那么需要具备什么条件 设mx为询问区间最大值,mn为询问区间最小值 mx - mn = (r - l) * k ...
- 【BZOJ4373】算术天才⑨与等差数列 线段树+set
[BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...
- 【BZOJ4373】算术天才⑨与等差数列 [线段树]
算术天才⑨与等差数列 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 算术天才⑨非常喜欢和等 ...
- BZOJ 4373 算术天才⑨与等差数列 线段树+set(恶心死我了)
mdzz,这道题重构了4遍,花了一个晚上... 满足等差数列的条件: 1. 假设min是区间最小值,max是区间最大值,那么 max-min+k(r−l) 2. 区间相邻两个数之差的绝对值的gcd=k ...
- BZOJ 4373算术天才⑨与等差数列(线段树)
题意:给你一个长度为n的序列,有m个操作,写一个程序支持以下两个操作: 1. 修改一个值 2. 给出三个数l,r,k, 询问:如果把区间[l,r]的数从小到大排序,能否形成公差为k的等差数列. n,m ...
- BZOJ 4373: 算术天才⑨与等差数列 线段树
Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能 ...
- bzoj 4373 算术天才⑨与等差数列——线段树+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 能形成公差为k的等差数列的条件:mx-mn=k*(r-l) && 差分 ...
- BZOJ4373 算术天才⑨与等差数列 【线段树】*
BZOJ4373 算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k ...
随机推荐
- 用Matlab实现字符串分割(split)
用Matlab实现字符串分割(split)Posted on 2011/08/08 Matlab的字符串处理没有C#强大,本身又没有提供OO特性,需要依赖别的手段完成这项任务. 我们在这里借助正则表达 ...
- SDUT 3928
Description C~K 和 PBH 经常玩一个游戏.游戏规则如下:现给定一个 n*n 的棋盘,一个石头被放在棋盘的左上角. 他们轮流移动石头.每一回合,两个人只能把石头向上,下,左,右四个方向 ...
- three.js_camera相机
https://blog.csdn.net/yangnianbing110/article/details/51275927 文章地址
- win10-idea2018
下载jar JetbrainsCrack-2.9-release-enc.jar idea64.exe.vmpotions 配置 -javaagent:D:\devsoft\idea\bin\Jetb ...
- weblogic 开启注意问题
1.关闭防火墙 service iptables stop chkconfig iptables off 2.weblogic unable to get file lock问题 我的解决办法是ps ...
- linux内核数据结构之链表【转】
转自:http://www.cnblogs.com/Anker/p/3475643.html 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结 ...
- ab的使用方法【转】
使用方法 ab -n 800 -c 800 http://192.168.0.10/ (-n发出800个请求,-c模拟800并发,相当800人同时访问,后面是测试url) ab -t 60 -c 1 ...
- caffe Python API 之中值转换
# 编写一个函数,将二进制的均值转换为python的均值 def convert_mean(binMean,npyMean): blob = caffe.proto.caffe_pb2.BlobPro ...
- Python下urllib2应用
#coding=utf-8 import urllib,urllib2 url = 'http://www.xxx.com' values = {'wd' : 'python', 'language' ...
- Linux Supervisor的安装与使用入门---SuSE
Linux Supervisor的安装与使用入门 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事 ...