bzoj4373 算术天才⑨与等差数列——线段树+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373
一个区间有以 k 为公差的数列,有3个条件:
1.区间 mx - mn = (r-l) * k;
2.差分数组的 gcd 是 k 的倍数;
3.没有重复出现的数;
其中1,2都可以用线段树维护,3用 set 维护每个数上一个出现的位置即可;
模仿TJ写的:https://blog.csdn.net/neither_nor/article/details/52461940
对 set 更熟悉了,细节还蛮多的。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
using namespace std;
int const maxn=3e5+;
int n,m,a[maxn],key,tot,pre[maxn];
map<int,int>h;
set<int>s[maxn<<];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int ab(int x){return x>?x:-x;}
struct N{
int mx,mn,fro,g;
friend N operator + (N x,N y)
{
N ret;
ret.mx=max(x.mx,y.mx);
ret.mn=min(x.mn,y.mn);
ret.fro=max(x.fro,y.fro);
ret.g=gcd(x.g,y.g);
return ret;//!
}
}t[maxn<<];
void build(int x,int l,int r)
{
if(l==r)
{
t[x].mn=t[x].mx=a[l]; t[x].g=ab(a[l+]-a[l]);
t[x].fro=pre[l]; return;
}
int mid=((l+r)>>);
build(x<<,l,mid); build(x<<|,mid+,r);
t[x]=t[x<<]+t[x<<|];
}
void update(int x,int l,int r,int p)
{
if(l==r)
{
t[x].mn=t[x].mx=a[l]; t[x].g=ab(a[l+]-a[l]);
t[x].fro=pre[l]; return;
}
int mid=((l+r)>>);
if(p<=mid)update(x<<,l,mid,p);
else update(x<<|,mid+,r,p);
t[x]=t[x<<]+t[x<<|];
}
N query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R)return t[x];
int mid=((l+r)>>);
if(mid<L)return query(x<<|,mid+,r,L,R);
else if(mid>=R)return query(x<<,l,mid,L,R);
else return query(x<<,l,mid,L,R)+query(x<<|,mid+,r,L,R);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(!h[a[i]])
{
h[a[i]]=++tot;
s[tot].insert();
s[tot].insert(n+);
}
int tmp=h[a[i]];
s[tmp].insert(i);
pre[i]=*--(s[tmp].insert(i).first);//
}
a[n+]=a[n];//!
build(,,n);
for(int i=,op,x,y,l,r,k;i<=m;i++)
{
scanf("%d",&op);
if(op==)
{
scanf("%d%d",&x,&y);
x^=key; y^=key;
int tmp,nxt,pr;
tmp=h[a[x]];
nxt=*s[tmp].upper_bound(x);
if(nxt!=n+)
{
pre[nxt]=pre[x];
update(,,n,nxt);
}
s[tmp].erase(x); if(!h[y])//
{
h[y]=++tot;
s[tot].insert();
s[tot].insert(n+);
}
tmp=h[y];
s[tmp].insert(x);
nxt=*s[tmp].upper_bound(x);
pre[x]=*--s[tmp].lower_bound(x);
if(nxt!=n+)
{
pre[nxt]=x;
update(,,n,nxt);
}
a[x]=y;
update(,,n,x);
if(x!=)update(,,n,x-);//
}
if(op==)
{
scanf("%d%d%d",&l,&r,&k);
l^=key; r^=key; k^=key;
if(l==r){key++; printf("Yes\n"); continue;}
N tmpp=query(,,n,l,r-);//
N tmp=tmpp+query(,,n,r,r);//
if(k==)
{
if(tmp.mx==tmp.mn)key++,printf("Yes\n");
else printf("No\n");
continue;
}
if(tmp.fro<l && tmp.mx==k*(r-l)+tmp.mn && tmpp.g%k==)//tmpp!
key++,printf("Yes\n");
else printf("No\n");
}
}
return ;
}
bzoj4373 算术天才⑨与等差数列——线段树+set的更多相关文章
- [BZOJ4373]算术天才⑨与等差数列(线段树)
[l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...
- 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 ...
随机推荐
- C# winform启动外部exe后,如何完全阻断父界面接收事件,扩展waitforexit
公司的系统搭载了好多奇奇怪怪的exe,以前启动exe后,系统还能接着操作.但是后面又提出额外的需求,说是打开外部exe之后,启动exe的父界面要完全不能进行任何操作.当然按常人所想再加一句waitfo ...
- 在python中调用js或者nodejs
在python中调用js或者nodejs要使用PyExecJs第三方包. pip install pyexecjs 示例代码 >>> import execjs >>&g ...
- Mac OS 小知识
删除Mac OS输入法中自动记忆的用户词组 有时候不小心制造了一个错误的词组,结果也被输入法牢牢记住,这时候可以用shift+delete组合键来删除 快捷键拾遗 Fn+Delet ...
- matplotlib命令与格式:标题(title),标注(annotate),文字说明(text)
1.title设置图像标题 (1)title常用参数 fontsize设置字体大小,默认12,可选参数 ['xx-small', 'x-small', 'small', 'medium', 'la ...
- IO编程——复制一个文件中的内容到另一个文件
public class TestIO { public static void main(String[] args) { File inputFile = new File("a.txt ...
- 【模板】求1~n的整数的乘法逆元
洛谷3811 先用n!p-2求出n!的乘法逆元 因为有(i-1)!-1=i!-1*i (mod p),于是我们可以O(n)求出i!-1 再用i!-1*(i-1)!=i-1 (mod p)即是答案 #i ...
- Android第三方开源下拉框:NiceSpinner
Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...
- 联赛前集训日记Day2
考试 倒数第二,我已经废了= = T1 那么水的点转区间都看不出来 T2 裸的线段树生打了个啥都不是的分块 T3 枚举想骗spj的部分分,结果啥都没有 GG 刷题 改题改的也是心累,现在蒙的要死 生活 ...
- 本地数据文件加载到hive表
1.在test数据库下创建表格 hive> create table vod_record_all( > watch_time date, > device_id string, & ...
- BlockQueue中ArrayBlockingQueue和LinkedBlockingQueue比较
LinkedBlockingQueue是BlockingQueue的一种使用Link List的实现,它对头和尾(取和添加操作)采用两把不同的锁,相对于ArrayBlockingQueue提高了吞吐量 ...