算术天才⑨非常喜欢和等差数列玩耍。
有一天,他给了你一个长度为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:算数天才与等差数列的更多相关文章

  1. BZOJ4373 算术天才⑨与等差数列 【线段树】*

    BZOJ4373 算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k ...

  2. [BZOJ4373]算术天才⑨与等差数列(线段树)

    [l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...

  3. 【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列

    hash大法好(@ARZhu):大数相乘及时取模真的是件麻烦事情 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次 ...

  4. BZOJ4373 算术天才⑨与等差数列(线段树)

    看上去很难维护,考虑找一些必要条件.首先显然最大值-最小值=k*(r-l).然后区间内的数需要模k同余.最后区间内的数两两不同(k=0除外).冷静一下可以发现这些条件组合起来就是充分的了. 考虑怎么维 ...

  5. BZOJ4373 算术天才与等差数列 题解

    题目大意: 一个长度为n的序列,其中第i个数为a[i].修改一个点的值询问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列. 思路: 1.一段区间符合要求满足:(1)区间中的max-min ...

  6. BZOJ4373 : 算术天才⑨与等差数列

    设$pre[i]$表示第$i$个数上一次出现的位置,$d[i]=abs(a[i]-a[i+1])$. 用线段树维护区间内$a$的最小值.最大值,$pre$的最大值以及$d$的$\gcd$. 对于询问$ ...

  7. BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)

    题意 题目链接 Sol 正经做法不会,听lxl讲了一种很神奇的方法 我们考虑如果满足条件,那么需要具备什么条件 设mx为询问区间最大值,mn为询问区间最小值 mx - mn = (r - l) * k ...

  8. bzoj4373 算术天才⑨与等差数列——线段树+set

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4373 一个区间有以 k 为公差的数列,有3个条件: 1.区间 mx - mn = (r-l) ...

  9. 【BZOJ4373】算术天才⑨与等差数列 线段树+set

    [BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...

随机推荐

  1. 一个可以拖拽的div

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Java微信小程序开发_00_资源帖

    1.微信小程序开发:http://blog.csdn.net/column/details/13721.html?&page=1 2.微信小程序栏目:http://blog.csdn.net/ ...

  3. 关于自动化与vTable两种暴露接口的区别-1未完......

    COM组件有两种暴露组件接口的方式,一种是以虚拟列表的方式暴露:一种就是自动化方式. 虚拟列表(VTable): COM组件将自己所有的方法的地址以一个虚拟表的方式存放在一起,这个虚拟表是一种结构,有 ...

  4. hdu-5861 Road(并查集)

    题目链接: Road Time Limit: 12000/6000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Pro ...

  5. bzoj3595 方伯伯的oj

    有$n$个数,一开始是$1~n$,有$m$次操作 1.把编号为$x$的人编号改为$y$,保证$y$没出现过 2.把编号为$x$的人提到第一名 3.把编号为$x$的人怼到最后一名 4.查询排名为$x$的 ...

  6. ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...

  7. How to manage concurrency in Django models

    How to manage concurrency in Django models The days of desktop systems serving single users are long ...

  8. bzoj 1711 Dining吃饭 —— 最大流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1711 食物一列,牛拆点,饮料一列. 代码如下: #include<cstdio> ...

  9. 转载:Android应用的自动更新模块

    软件的自动更新一般都与Splash界面绑定在一起, 由于需要维护的软件界面很复杂, 一个Activity中嵌入ViewPager, 并且逻辑比较复杂, 索性重新写一个Activity, 现在的软件都很 ...

  10. [FATAL_ERROR] Uncaught PDOException: There is already an active transaction

    [FATAL_ERROR] Uncaught PDOException: There is already an active transaction ... $mysql->beginTran ...