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# 字符串的入门
1."@"表示字符串中的"\"不当成转义符. 2.转义符或者特殊处理的一些字符只是针对于代码中直接写出的字符串中,对于程序运行中读取出来的转义符或者特殊处理的字 ...
- Python语言之变量1(数值,字符串,布尔)
1.数值 整数:2, -2 长整数:2**1024, 2**2048(真的可以很~长~~~,手残算了个2**100000,IDLE还真给打出来了,ORZ) 浮点数:7.05, 1E2(100.0), ...
- HDU_4826_dp
Labyrinth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Review:Microbiota, metagenome, microbiome傻傻分不清
Microbiota 微生物群 微生物群是指研究动植物体上共生或病理的微生物生态群体.微生物群包括细菌.古菌.原生动物.真菌和病毒.研究表明其在宿主的免疫.代谢和激素等方面非常重要.近义词Micr ...
- CentOS 7 不能连接网路的解决方法
---恢复内容开始--- 刚安装的CentOS7 是不能连接网络的,更不能使用yum 进行应用的安装 (1)通过ip addr或者是 ifconfig获取需要编辑的文件名 (2)vi /etc/sys ...
- Asp.Mvc 常用
url转义 var address = "http://www.cnblog.com"; var a22 = Uri.EscapeDataString(address); var ...
- =、==、is、id(内容)
= 赋值 == 比较值是否相等 is 比较.比较的是内存地址 id(内容) 测出内存地址
- python爬虫11 | 这次,将带你爬取b站上的NBA形象大使蔡徐坤和他的球友们
在上一篇中 python爬虫10 | 网站维护人员:真的求求你们了,不要再来爬取了!! 小帅b给大家透露了我们这篇要说的牛逼利器 selenium + phantomjs 如果你看了 python爬虫 ...
- BZOJ 1606 USACO 2008 Dec. 购买干草
[题意概述] 有n件物品,每件物品有体积Vi,背包容量为C,问最多可以装多少体积的物品 [题解] 显然是个无限背包嘛.. 直接做背包DP就好 注意无限背包的写法和01背包的区别 #include< ...
- CTF中编码与加解密总结
CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...