bzoj4373:算数天才与等差数列
算术天才⑨非常喜欢和等差数列玩耍。
有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。
他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。
当然,他还会不断修改其中的某一项。
为了不被他鄙视,你必须要快速并正确地回答完所有问题。
注意:只有一个数的数列也是等差数列。第一行包含两个正整数n,m(1<=n,m<=300000),分别表示序列的长度和操作的次数。
第二行包含n个整数,依次表示序列中的每个数a[i](0<=a[i]<=10^9)。
接下来m行,每行一开始为一个数op,
若op=1,则接下来两个整数x,y(1<=x<=n,0<=y<=10^9),表示把a[x]修改为y。
若op=2,则接下来三个整数l,r,k(1<=l<=r<=n,0<=k<=10^9),表示一个询问。
在本题中,x,y,l,r,k都是经过加密的,都需要异或你之前输出的Yes的个数来进行解密。
这道题用检验累加和/平方和的方式水过了。。最后发现是质数太大,乘起来溢出了。。。。。。
调了我三天(蠢哭了)
#include <cstdio>
#include <utility>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> ll;
//#define debug #ifdef debug
const LL maxn=, prime=1e9+;
#else
const LL maxn=3e5+, prime=1e9+;
#endif
LL n, m, cntyes;
//可以捆绑♂到一起,这样查询更新都方便
LL seg_sum[maxn*], seg_sqr[maxn*], maxm[maxn*], minm[maxn*];
LL flag, *seg, POS, L, R, v; inline LL max(LL x, LL y) { return x<y?y:x; }
inline LL min(LL x, LL y) { return x<y?x:y; }
inline void swap(LL &x, LL &y) { LL t=x; x=y; y=t; } void modify(LL now, LL l, LL r){ //其实可以四个一起修改
if (l>r||l>POS||r<POS) return;
if (l==r) {
if (flag==) maxm[now]=minm[now]=v;
if (flag==) seg_sum[now]=v, seg_sqr[now]=v*v%prime;
return;
}
LL mid=(l+r)>>;
modify(now<<, l, mid); modify(now<<|, mid+, r);
if (flag==){
maxm[now]=max(maxm[now<<], maxm[now<<|]);
minm[now]=min(minm[now<<], minm[now<<|]);
}
if (flag==) {
seg_sum[now]=(seg_sum[now<<]+seg_sum[now<<|])%prime;
seg_sqr[now]=(seg_sqr[now<<]+seg_sqr[now<<|])%prime;
}
} ll query(LL now, LL l, LL r){ //其实可以四个一起查询
if (l>r||l>R||r<L){
if (flag==) return make_pair(1e9, );
if (flag==) return make_pair(, );
}
if (l>=L&&r<=R){
if (flag==)
return make_pair(minm[now], maxm[now]);
if (flag==)
return make_pair(seg_sum[now], seg_sqr[now]);
}
LL mid=(l+r)>>;
ll pair1, pair2;
pair1=query(now<<, l, mid); pair2=query(now<<|, mid+, r);
if (flag==)
return make_pair(min(pair1.first, pair2.first),
max(pair1.second, pair2.second));
if (flag==)
return make_pair((pair1.first+pair2.first)%prime,
(pair1.second+pair2.second)%prime);
return make_pair(-, -);
} int main(){
scanf("%lld%lld", &n, &m);
LL value;
for (LL i=; i<=n; ++i){
scanf("%lld", &value);
flag=, POS=i, v=value;
modify(, , n);
flag=, POS=i, v=value;
modify(, , n);
}
LL op, x, y, l, r, k;
for (LL i=; i<m; ++i){
scanf("%lld", &op);
if (op==){
scanf("%lld%lld", &x, &y);
x^=cntyes, y^=cntyes;
flag=, POS=x, v=y;
modify(, , n);
flag=;
modify(, , n);
}
LL h, t, qsum, qsqr, vecsum, vecsqr;
if (op==){
scanf("%lld%lld%lld", &l, &r, &k);
l^=cntyes, r^=cntyes, k^=cntyes;
if (l==r){
++cntyes;
printf("Yes\n");
continue;
}
if (l>r) swap(l, r);
//查询最大最小值
flag=, L=l, R=r;
ll re=query(, , n);
//h:等差队列最小值,t:等差队列最大值
h=re.first, t=re.second;
if (k*(r-l)!=t-h){
printf("No\n"); continue;
}
//查询区间和
flag=, L=l, R=r;
re=query(, , n);
qsum=re.first, qsqr=re.second;
vecsum=(h+t)*(r-l+)/;
vecsum%=prime; //忘记模了。。
LL n=r-l+;
//计算等差数列的平方和 h:a1 k:d l=r时要特判!!!
vecsqr=(h*h%prime*n%prime+
(+n-)*n%prime*h%prime*k%prime)%prime+
k*k%prime*((n-)*n%prime*(*n-)/%prime);
vecsqr%=prime;
if (qsum==vecsum&&qsqr==vecsqr){
++cntyes;
printf("Yes\n");
}
else printf("No\n");
}
}
return ;
}
bzoj4373:算数天才与等差数列的更多相关文章
- BZOJ4373 算术天才⑨与等差数列 【线段树】*
BZOJ4373 算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k ...
- [BZOJ4373]算术天才⑨与等差数列(线段树)
[l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...
- 【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列
hash大法好(@ARZhu):大数相乘及时取模真的是件麻烦事情 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次 ...
- BZOJ4373 算术天才⑨与等差数列(线段树)
看上去很难维护,考虑找一些必要条件.首先显然最大值-最小值=k*(r-l).然后区间内的数需要模k同余.最后区间内的数两两不同(k=0除外).冷静一下可以发现这些条件组合起来就是充分的了. 考虑怎么维 ...
- BZOJ4373 算术天才与等差数列 题解
题目大意: 一个长度为n的序列,其中第i个数为a[i].修改一个点的值询问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列. 思路: 1.一段区间符合要求满足:(1)区间中的max-min ...
- BZOJ4373 : 算术天才⑨与等差数列
设$pre[i]$表示第$i$个数上一次出现的位置,$d[i]=abs(a[i]-a[i+1])$. 用线段树维护区间内$a$的最小值.最大值,$pre$的最大值以及$d$的$\gcd$. 对于询问$ ...
- BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)
题意 题目链接 Sol 正经做法不会,听lxl讲了一种很神奇的方法 我们考虑如果满足条件,那么需要具备什么条件 设mx为询问区间最大值,mn为询问区间最小值 mx - mn = (r - l) * k ...
- bzoj4373 算术天才⑨与等差数列——线段树+set
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 一个区间有以 k 为公差的数列,有3个条件: 1.区间 mx - mn = (r-l) ...
- 【BZOJ4373】算术天才⑨与等差数列 线段树+set
[BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...
随机推荐
- Ueditor--toolbars
(1)代码中定义 <script id="container" name="content" type="text/plain"> ...
- io.js的六大新特性
io.js是nodejs的友好版的分支("friendly fork”).它支持npm中所有的同样模块,且使用了v8最新版本的截取(v8是被node.js使用js解释器),且修复了很多的bu ...
- Linux-NoSQL之Redis(二)
一.Redis配置文件详解 1.通用配置 daemonize no # 默认情况下,redis并不是以daemon形式来运行的.通过daemonize配置项可以控制redis的运行形式 pidfil ...
- tensorflow训练验证码识别模型
tensorflow训练验证码识别模型的样本可以使用captcha生成,captcha在linux中的安装也很简单: pip install captcha 生成验证码: # -*- coding: ...
- hdu2196 Computer待续
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #i ...
- 51Nod1766 树上的最远点对
1766 树上的最远点对 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i&l ...
- 【LeetCode】010. Regular Expression Matching
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- 【Lintcode】364.Trapping Rain Water II
题目: Given n x m non-negative integers representing an elevation map 2d where the area of each cell i ...
- Java中Calendar/SimpleDateFormat/Date常用方法总结
//获取当前时刻yyyy-MM-dd HH:mm:ss Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = new S ...
- Wireshark抓取本地Tcp包(任何数据包)
没有任何一个程序员在做项目的时候不会遇到网络编程的问题,要解决这些问题除了对各种网络协议深入了解之外,还需要掌握各种网络分析工具的用法,不用多说wireshark绝对是这方面的翘楚,可惜的是,wire ...