hash大法好(@ARZhu);大数相乘及时取模真的是件麻烦事情

Description

算术天才⑨非常喜欢和等差数列玩耍。
有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。
他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。
当然,他还会不断修改其中的某一项。
为了不被他鄙视,你必须要快速并正确地回答完所有问题。
注意:只有一个数的数列也是等差数列。

Input

第一行包含两个正整数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的个数来进行解密。

Output

输出若干行,对于每个询问,如果可以形成等差数列,那么输出Yes,否则输出No。

Sample Input

5 3
1 3 2 5 6
2 1 5 1
1 5 4
2 1 5 1

Sample Output

No
Yes

题目分析

动态询问区间是否为「等差数列」。出题人用线段树维护了区间最小;区间gcd;区间……等等一系列标记。

然而HZQ给出了一个吊打出题人的做法:线段树hash。

注意到询问的区间可以视作集合形式,与顺序无关。于是便可以快速地集合hash。

具体来说用线段树维护区间最小值(用于寻找等差数列首项);区间立方和(由费马大定理得立方和不容易被卡;不过在这题出题人并没有恶意卡平方哈希)

问题就在于如何快速验证;换句话说就是计算询问的等差数列的hash值$x^3+(x+k)^3+(x+2*k)^3+...+(x+(n-1)*k)^3$其中$n$为序列长度

把式子按照指数展开,就可以愉快地$O(1)$计算数列答案了。我才没有暴力展开算了1h什么都没算出来

  1 #include<bits/stdc++.h>
  2 typedef long long ll;
  3 const ll MO = 1e9+7;
  4 const int INF = 2e9;
  5 const int maxn = 300035;
  6
  7 int n,m,preans;
  8 ll mn[maxn<<2],f[maxn<<2];
  9
 10 int read()
 11 {
 12     char ch = getchar();
 13     int num = 0;
 14     bool fl = 0;
 15     for (; !isdigit(ch); ch = getchar())
 16         if (ch=='-') fl = 1;
 17     for (; isdigit(ch); ch = getchar())
 18         num = (num<<1)+(num<<3)+ch-48;
 19     if (fl) num = -num;
 20     return num;
 21 }
 22 ll qmi(ll a, ll b)
 23 {
 24     ll ret = 1;
 25     while (b)
 26     {
 27         if (b&1) ret = ret*a%MO;
 28         a = a*a%MO, b >>= 1;
 29     }
 30     return ret;
 31 }
 32 void pushup(int rt)
 33 {
 34     mn[rt] = std::min(mn[rt<<1], mn[rt<<1|1]);
 35     f[rt] = (f[rt<<1]+f[rt<<1|1])%MO;
 36 }
 37 void build(int rt, int l, int r)
 38 {
 39     mn[rt] = INF;
 40     if (l==r){
 41         mn[rt] = f[rt] = read();
 42         f[rt] = 1ll*f[rt]*f[rt]%MO*f[rt]%MO;
 43         return;
 44     }
 45     int mid = (l+r)>>1;
 46     build(rt<<1, l, mid), build(rt<<1|1, mid+1, r);
 47     pushup(rt);
 48 }
 49 void update(int rt, int l, int r, int pos, ll c)
 50 {
 51     if (l==r){
 52         f[rt] = c*c%MO*c%MO, mn[rt] = c;
 53         return;
 54     }
 55     int mid = (l+r)>>1;
 56     if (pos <= mid) update(rt<<1, l, mid, pos, c);
 57     else update(rt<<1|1, mid+1, r, pos, c);
 58     pushup(rt);
 59 }
 60 int queryMn(int rt, int L, int R, int l, int r)
 61 {
 62     if (L <= l&&r <= R) return mn[rt];
 63     int mid = (l+r)>>1, ret = INF;
 64     if (L <= mid)
 65         ret = queryMn(rt<<1, L, R, l, mid);
 66     if (R > mid) ret = std::min(ret, queryMn(rt<<1|1, L, R, mid+1, r));
 67     return ret;
 68 }
 69 ll query(int rt, int L, int R, int l, int r)
 70 {
 71     if (L <= l&&r <= R) return f[rt]%MO;
 72     int mid = (l+r)>>1;
 73     ll ret = 0;
 74     if (L <= mid) ret = query(rt<<1, L, R, l, mid);
 75     if (R > mid) ret += query(rt<<1|1, L, R, mid+1, r);
 76     return ret%MO;
 77 }
 78 ll calc(ll x, ll n, ll k)
 79 {
 80     ll ret = n*x%MO*x%MO*x%MO, pos = 1ll*n*(n-1)%MO*qmi(2, MO-2)%MO;
 81     ret += ((k*k%MO*k%MO*pos%MO*pos%MO+3*k%MO*x%MO*x%MO*pos%MO)%MO+k*x%MO*k%MO*(2*n-1)%MO*pos%MO)%MO;
 82     return ret%MO;          //时刻记得要取模!
 83 }
 84 int main()
 85 {
 86 //    freopen("4373.in","r",stdin);
 87 //    freopen("4373.out","w",stdout);
 88     n = read(), m = read();
 89     build(1, 1, n);
 90     for (int i=1; i<=m; i++)
 91     {
 92         int opt = read();
 93         if (opt==1){
 94             int x = read()^preans, y = read()^preans;
 95             update(1, 1, n, x, y);
 96         }else{
 97             int l = read()^preans, r = read()^preans, k = read()^preans, lens = (r-l+1);
 98             int st = queryMn(1, l, r, 1, n);
 99             ll sum = query(1, l, r, 1, n);
100             if (calc(st, lens, k)==sum) preans++, puts("Yes");
101             else puts("No");
102         }
103     }
104     return 0;
105 }

END

转载于:https://www.cnblogs.com/antiquality/p/9364412.html

【线段树 集合hash】bzoj4373: 算术天才⑨与等差数列相关推荐

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

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

  2. [bzoj4373]算术天才⑨与等差数列

    //被标题吸引进来,无论如何都要切出来 题目大意 给你一个长度为n的序列,有m个操作,写一个程序支持以下两个操作: 1. 修改一个值 2. 给出三个数l,r,k,询问:如果把区间[l,r]的数从小到大 ...

  3. 线段树 + 字符串Hash - Codeforces 580E Kefa and Watch

    Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是 ...

  4. 【BZOJ4373】算术天才⑨与等差数列

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

  5. POJ2528 线段树+离散化+hash(成段更新)

    题目:Mayor's posters 题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报 思路:这题数据范围很大,直接搞超时+超内存,需要离散化: 离散化简单的来说就是只取我们需要的值来用, ...

  6. P5278 算术天才⑨与等差数列 题解

    一道不错的题目,只不过能被 hash 和维护若干次方和通过,本篇讲正解. 考虑一个乱序序列重排后是等差数列的一些条件(设区间 [ l , r ] [l,r] [l,r],公差为 d d d): 数列最 ...

  7. 互达的集合(线段树)

    problem 给定数组 l,rl,rl,r.求有多少个非空集合 SSS,满足 ∀i,j∈Sli≤j≤ri\forall_{i,j\in S}\ l_i\le j\le r_i∀i,j∈S​ li​≤ ...

  8. 线段树 ---- CF452F. Permutation(线段树维护序列Hash)

    题目链接 题目大意: 就是给你一个全排列,问你是否存在一个c=a+b2c=\frac{a+b}{2}c=2a+b​ 满足ccc的位置在a,ba,ba,b之间 解题思路: 首先我们先按顺序遍历,我们假设 ...

  9. P6688-可重集【字符串hash,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P6688 解题思路 nnn个数,每次有操作 修改一个数 询问两个区间是否他们中的元素分别组成的可重集合A,BA,BA ...

最新文章

  1. CUDA上深度学习模型量化的自动化优化
  2. 汇编 编程实现从键盘输入三位以内的十进制负数_macOS上的汇编入门(二)——数学基础...
  3. Python中九种格式化输出方法,你都知道吗?
  4. 笔记2深度学习 梯度和梯度法
  5. STM32工作笔记005---STM32芯片解读
  6. Linux替代Windows系统软件比拼
  7. css之div兼容性问题
  8. 轻量级小型网站导航条
  9. 计算机图形学基础-第二章 VB.NET 绘图基础
  10. 什么是Vagrant 以及作用
  11. 显示器知识:分辨率1080P、2K、4K、8K相关知识介绍,看完你就懂了!
  12. 安徽省淮南市谷歌卫星地图下载
  13. 区块链+医疗:隐藏的百亿级市场?
  14. 对计算机专业学生的七个建议(作者:Joel Spolsky)
  15. 今年巴菲特的午餐上,躺着流血的地产商
  16. Linux之进程的前后台切换
  17. 《Laravel-汉字转拼音》
  18. 硬件趣学python_硬的解释|硬的意思|汉典“硬”字的基本解释
  19. Basic grammer
  20. java基于springboot框架实现的环保网站垃圾分类系统实战项目

热门文章

  1. IOS 通讯录 右侧的字母栏
  2. rip协议的V1和V2的更新机制
  3. 3Com发布新MSR路由器 为企业提供视频播客支持
  4. 语音交互编程语言了解一下?
  5. xfce中仿gnome的多桌面的xfdashboard的用法
  6. sc.textFile的相对路径与绝对路径
  7. logs is not in the form of topic-partition or topic-partition.uniqueId-delete
  8. Ubuntu16.04下面壁纸切换软件variety设置
  9. 计算机系统基础:程序与运算
  10. wpf调用其他项目界面_WPF开发Prism框架实现一个简单播放器