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 ...
随机推荐
- [Windows Server 2012] 服务器安全加固
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:服务器安全加固 ...
- 【VHDL】深度讲解二进制无符号和有符号加法处理溢出的问题
1.Unsigned adders 这个比较简单,只需在A.B前面扩展一位0防止溢出,溢出的数填到第n位cout,n-1到0位就是sum. , 2.Signed adders 一开始也搞不懂下图中为什 ...
- python os os.path模块学习笔记
#!/usr/bin/env python #coding=utf-8 import os #创建目录 os.mkdir(r'C:\Users\Silence\Desktop\python') #删除 ...
- PHP采用301跳转方式防CC拦截
PHP采用301跳转方式防CC拦截 降低CC攻击的效果 <?php empty($_SERVER['HTTP_VIA']) or exit('Access Denied'); $second ...
- js 简单小知识
1. javascript的typeof返回哪些数据类型: string, boolean, number, undefined, function, object 2. split() join() ...
- Cat VS Dog HDU_3829(最大独立集最大匹配)
Cat VS Dog 题意:一群小朋友去动物园,如果每个小朋友喜欢的动物是猫,那么不喜欢的动物一定是狗,反之也是.现在动物园的管理者要拿走一些动物,如果拿走的是某个小朋友不喜欢的动物,那这个小朋友就非 ...
- vue项目中的常见问题(vue-cli版本3.0.0)
一.样式问题 1.vue中使用less 安装less依赖 npm install less less-loader --save-dev 在使用时 在style标签中加入 lang="les ...
- navicate远程访问ubuntu上的mysql数据库
安装mysql 首先检查系统中是否已经安装了MySQL,在终端里面输入: sudo netstat -tap | grep mysql 如上所示就是正确安装并启动,启动命令为 sudo /etc/in ...
- Lucas小记
组合数学全忘了 记笔记记笔记 做个简单题 代码 from bzoj4403 #include <stdio.h> #define p 1000003 typedef long long l ...
- Leetcode 39.组合总数
组合总数 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限 ...