[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 ...
随机推荐
- 【CodeForces】899 E. Segments Removal
[题目]E. Segments Removal [题意]给定n个数字,每次操作删除最长的连续相同数字(等长删最左),求全部删完的最少次数.n<=2*10^6,1<=ai<=10^9. ...
- python3之json模块使用
1. json模块介绍 json是python自带的操作json的模块. python序列化为json时的数据类型转换关系: python格式 json格式 dict(复合类型) object lis ...
- TinyOS 代码分析
1.Basestation案例 位于/opt/tinyos-main-master/apps/Basetation 1.1本例的顶层结构图: 1.2软件实现流程 1) uartIn,uartOut ...
- 大美西安writeup
http://202.112.51.184:10080/ admin/admin 弱口令登入 发现注入 但是这个注入实在是不知道怎么利用.很蛋疼.后来get了一个姿势. 先-1让前面的不被下载然后后面 ...
- $NTT$(快速数论变换)
- 概念引入 - 阶 对于$p \in N_+$且$(a, \ p) = 1$,满足$a^r \equiv 1 (mod \ p)$的最小的非负$r$为$a$模$p$意义下的阶,记作$\delta_p ...
- freemarker模板引擎的使用
freemarker是一套前端模板引擎,在使用时,要先在web项目中添加freemarker.jar的依赖. 我在这里主要演示spring-mvc整合freemarker模板引擎.项目案例的文件包结构 ...
- 开源介绍:Google Guava、Google Guice、Joda-Time
一.Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency lib ...
- html基础--css基本属性
HTML基础--css基本属性 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- Oracle数据库(64位) 及 PLSQL(64位)的组合安装【第一篇】
目前PC端普遍使用64位操作系统,64位操作系统在性能上比32位更佳,但是兼容性上则不如32的操作系统,Oracle提供了64和32两种版本,而PLsql工具则只有32位,在这篇文章详细的讲述了如何在 ...
- DB2和Oracle中Date比较