题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373

能形成公差为k的等差数列的条件:mx-mn=k*(r-l) && 差分数组gcd为k  && 区间内没有重复的数。

这些都可以线段树维护。

那个“没有重复的数”需要给每个位置记下权值的pre,修改的时候需要找到它前面一个和后面一个。

用链表的话没法插入。可以给每个权值开一个set,就能用lower_bound了。

有些细节。重载运算符很方便。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
using namespace std;
const int N=3e5+,INF=1e9+;
int n,m,c[N],ls[N<<],rs[N<<],tot,pre[N],lt,cnt;
map<int,int> mp;
set<int> s[N<<];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int abss(int k){return k<?-k:k;}
struct Node{
int mx,mn,lst,g;
Node(int a=,int b=,int l=,int g=):mx(a),mn(b),lst(l),g(g) {}
Node operator+ (const Node &b)const
{
return Node(max(mx,b.mx),min(mn,b.mn),max(lst,b.lst),gcd(g,b.g));
}
}a[N<<];
void add(int x)
{
mp[x]=++cnt;s[cnt].insert();s[cnt].insert(n+);
}
void pshp(int cr)
{
a[cr]=a[ls[cr]]+a[rs[cr]];
}
void build(int l,int r,int cr)
{
if(l==r)
{
a[cr]=Node(c[l],c[l],pre[l],abss(c[l+]-c[l]));return;
}
int mid=((l+r)>>);
ls[cr]=++tot;build(l,mid,ls[cr]);
rs[cr]=++tot;build(mid+,r,rs[cr]);
pshp(cr);//!!!
}
void updt(int l,int r,int cr,int p)
{
if(l==r)
{
a[cr]=Node(c[l],c[l],pre[l],abss(c[l+]-c[l]));return;
}
int mid=((l+r)>>);
if(p<=mid)updt(l,mid,ls[cr],p);
else updt(mid+,r,rs[cr],p);
pshp(cr);
}
Node query(int l,int r,int cr,int L,int R)
{
if(l>=L&&r<=R)return a[cr];
int mid=((l+r)>>);
if(L>mid)return query(mid+,r,rs[cr],L,R);
if(R<=mid)return query(l,mid,ls[cr],L,R);
return query(l,mid,ls[cr],L,R)+query(mid+,r,rs[cr],L,R);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&c[i]);
if(!mp[c[i]])add(c[i]);
int t=mp[c[i]];
pre[i]=*--s[t].lower_bound(i);
s[t].insert(i);
}
a[n+]=a[n];//?是为了让最后一个点的差分是0,使不影响吧
tot=;build(,n,);
int op,x,y;
while(m--)
{
scanf("%d",&op);
if(op==)
{
scanf("%d%d",&x,&y);x^=lt;y^=lt;
int t=mp[c[x]];
int u=*--s[t].lower_bound(x),v=*s[t].upper_bound(x);
if(v!=n+)pre[v]=u,updt(,n,,v);//v!=n+1
s[t].erase(x);
if(!mp[y])add(y);t=mp[y];
u=*--s[t].lower_bound(x);v=*s[t].upper_bound(x);
if(v!=n+)pre[v]=x,updt(,n,,v);//v!=n+1
pre[x]=u;c[x]=y;s[t].insert(x);
updt(,n,,x);
if(x!=)updt(,n,,x-);//x!=1//为了改差分
}
else
{
int L,R,k;
scanf("%d%d%d",&L,&R,&k);L^=lt;R^=lt;k^=lt;
if(L==R){printf("Yes\n");lt++;continue;}//放在下面那个if的上面!
Node ans0=query(,n,,L,R-),ans=ans0+query(,n,,R,R);//为了差分弄ans0
if(!k) //放在下面那个if的上面!
{
if(ans.mx==ans.mn)printf("Yes\n"),lt++;
else printf("No\n");
continue;
}
if(ans.lst<L&&ans.mx-ans.mn==k*(R-L)&&ans0.g==k)printf("Yes\n"),lt++;
else printf("No\n");
}
}
return ;
}

最新文章

  1. Python Web 方向(一)
  2. HTTP,FTP,TCP,UDP及SOCKET
  3. 首页自动生成静态化html
  4. Lex&amp;Yacc Parser错误发生后再次parser之前恢复初始状态
  5. Servers
  6. Redis存储Tomcat集群的Session
  7. 利用a标签解析URL
  8. 直接拿来用!最火的Android开源项目(二)(转)
  9. 40. Interleaving String
  10. java 12-2 String和StringBuffer之间的转换
  11. File类和RandomAccessFile类
  12. C++多态的实现及原理详细解析
  13. Python概述_软件安装_常见问题
  14. 删除qq历史签名
  15. 《Python CookBook2》 第一章 文本 - 每次处理一个字符 &amp;&amp; 字符和字符值之间的转换
  16. 基于PlatinumKit库的DLNA服务端开发
  17. SQLSERVER2012的分页新功能
  18. 全局唯一ID发号器的几个思路
  19. 深入理解 Python 中的上下文管理器
  20. zip4j实现文件压缩与解压缩 &amp; common-compress压缩与解压缩

热门文章

  1. 海量可视化日志分析平台之ELK搭建
  2. C#窗体代码相关笔记
  3. [Noip 2013 Day1-3] 货车运输 做法总结
  4. Leetcode148. Sort List排序链表
  5. node vue 微信公众号(三)启用本地服务器
  6. Sentinel 发布里程碑版本,添加集群流控功能
  7. 洛谷 P1242 新汉诺塔
  8. php链表笔记:合并两个有序链表
  9. 关于SqlServer的内连接,外链接以及left join,right join之间的一些问题与区别。
  10. pycharm优化