【莫队】【P3901】 数列找不同
Description
现在有一个长度为\(~n~\)的数列\(~A_1~,~A_2~\dots~A_n~\),\(~Q~\)个询问\(~[l_i~,~r_i]~\),每次询问区间内是否有元素相同
Input
第一行有两个整数\(~N,Q~\),
第二行有\(~n~\)个整数,代表这个序列
以下\(~Q~\)行每行两个整数,代表询问区间
Output
对每个询问输出一行\(~Yes~\)或\(~No~\)。
Hint
\(Forall:\)
\(1~\leq~n~,~Q~\leq~10^5~,~1~\leq~A_i~\leq~N~,~1~\leq~l_i~\leq~r_i~\leq~N\)
Solution
看到这题发现可以用莫队做。然鹅统计区间出现次数平方的题写腻了,而开桶和位向量的做法又很麻烦,于是我就YY了一个更加麻烦的做法。
发现我们可以在莫队维护区间信息的时候维护区间中所有元素出现次数之积。因为乘1等价于没有乘,我们对于没有出现的元素也乘1。这个值在指针移动时是支持修改的:只要在去掉该位置贡献的时候除掉当前的出现次数,然后将这个位置的出现次数\(-1\),再乘回去即可。增加一个位置贡献的方法同理。当询问的区间出现次数积为\(1\)时,即为没有出现重复,否则为出现重复。
但是考虑这么做在极端数据,比如前\(\frac{n}{2}\)个数出现了\(2\)次,后\(\frac{n}{2}\)个数没有出现的时候,积是\(2^{\frac{n}{2}}\)次方,显然存不下。这时考虑NOIP2014解方程,我们只需要对多个形如1******7的大质数取模,当所有取模后的答案都为\(1\)是,我们认为积是\(1\),否则积显然不是\(1\)。
于是先\(O(n)\)筛一下逆元再莫队就好了。
Code
这个代码写的好丑啊……其实可以美化美化然而我懒得写了
#include<cmath>
#include<cstdio>
#include<algorithm>
#ifdef ONLINE_JUDGE
#define puts(o) \
puts("I am a cheater!")
#define freopen(a,b,c)
#endif
#define rg register
#define ci const int
#define cl const long long
typedef long long int ll;
template <typename T>
inline void qr(T &x) {
rg char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
}
namespace IO {
char buf[120];
}
template <typename T>
inline void qw(T x,const char aft,const bool pt) {
if(x < 0) {x=-x,putchar('-');}
rg int top=0;
do {IO::buf[++top]=x%10+'0';} while(x/=10);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}
const int maxn = 100010;
const int ccnt = 6;
int n,q;
int MU[maxn],belong[maxn],bk[maxn];
int inv[8][maxn];
struct Ask {
int l,r,num;
bool ans;
inline bool operator<(const Ask &_others) const {
if(belong[this->l] != belong[_others.l]) return this->l < _others.l;
if(belong[this->l] & 1) return this->r < _others.r;
else return this->r > _others.r;
}
};
Ask ask[maxn];
inline bool cmp(const Ask &_a,const Ask &_b) {
return _a.num < _b.num;
}
struct C {
int mod;
int ans;
C(int _x=0) {mod=_x,ans=1;}
};
C CU[8];
void GetInv(ci,ci);
int main() {
freopen("1.in","r",stdin);
qr(n);qr(q);
for(rg int i=1;i<=n;++i) qr(MU[i]);
for(rg int i=1,sn=sqrt(n);i<=n;++i) belong[i]=i/sn;
for(rg int i=1;i<=q;++i) {
qr(ask[i].l);qr(ask[i].r);ask[i].num=i;
}
CU[1]=C(1000000007);CU[2]=C(1000000009);CU[3]=C(19260817);CU[4]=C(998244353);CU[5]=C(10000007);
for(int i=1;i<ccnt;++i) GetInv(CU[i].mod,i);
std::sort(ask+1,ask+1+q);
int prel=ask[1].l,prer=ask[1].l-1;
#define jd(o) (bk[MU[o]] > 1)
for(rg int i=1;i<=q;++i) {
int l=ask[i].l,r=ask[i].r;
while(prel < l) {
if(jd(prel)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*inv[j][bk[MU[prel]]]%CU[j].mod;
}
--bk[MU[prel]];
if(jd(prel)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*bk[MU[prel]]%CU[j].mod;
}
++prel;
}
while(prel > l) {
--prel;
if(jd(prel)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*inv[j][bk[MU[prel]]]%CU[j].mod;
}
++bk[MU[prel]];
if(jd(prel)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*bk[MU[prel]]%CU[j].mod;
}
}
while(prer < r) {
++prer;
if(jd(prer)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*inv[j][bk[MU[prer]]]%CU[j].mod;
}
++bk[MU[prer]];
if((jd(prer))) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*bk[MU[prer]]%CU[j].mod;
}
}
while(prer > r) {
if(jd(prer)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*inv[j][bk[MU[prer]]]%CU[j].mod;
}
--bk[MU[prer]];
if(jd(prer)) {
for(rg int j=1;j<ccnt;++j) CU[j].ans=1ll*CU[j].ans*bk[MU[prer]]%CU[j].mod;
}
--prer;
}
bool _ans=true;
for(rg int j=1;j<ccnt;++j) if(CU[j].ans != 1) {
_ans=false;break;
}
ask[i].ans=_ans;
}
#undef jd
std::sort(ask+1,ask+1+q,cmp);
for(rg int i=1;i<=q;++i)
if(ask[i].ans) puts("Yes");
else puts("No");
return 0;
}
void GetInv(ci mod,ci cur) {
inv[cur][1]=1;
for(rg int i=2;i<=n;++i) inv[cur][i]=1ll*(mod-mod/i)*inv[cur][mod%i]%mod;
}
Summary
貌似这次没啥好summary的
【莫队】【P3901】 数列找不同的更多相关文章
- P3901 数列找不同
P3901 数列找不同 题目描述 现有数列 \(A_1,A_2,\cdots,A_N\) ,Q 个询问 \((L_i,R_i)\) , \(A_{Li} ,A_{Li+1},\cdots,A_{Ri} ...
- Luogu P3901 数列找不同
由于技术原因,题目我贴不上了,大家点下面的链接自己去看吧^_^ P3901 数列找不同 这题第一眼看去,题面真短,有坑(flag) 在往下面看去,woc数据这么大,你要怎样. 现在一起想想想,超级侦探 ...
- 洛谷P3901 数列找不同 [莫队]
题目传送门 题目描述 现有数列 A_1,A_2,\cdots,A_NA1,A2,⋯,AN ,Q 个询问 (L_i,R_i)(Li,Ri) , A_{Li} ,A_{Li+1},\cdots, ...
- 洛谷 P3901 数列找不同(莫队)
题目链接:https://www.luogu.com.cn/problem/P3901 这道题简单莫队模板题,然后$add$和$del$分别处理$vis[]$从$0-->1$和从$1--> ...
- 洛谷P3901 数列找不同(莫队)
传送门 我不管我不管我就是要用莫队 直接用莫队裸上 //minamoto #include<iostream> #include<cstdio> #include<alg ...
- 【刷题】洛谷 P3901 数列找不同
题目描述 现有数列 \(A_1,A_2,\cdots,A_N\) ,Q 个询问 \((L_i,R_i)\) , \(A_{Li} ,A_{Li+1},\cdots,A_{Ri}\) 是否互不相同 输入 ...
- 【题解】Luogu P3901 数列找不同
我博客中对莫队的详细介绍 原题传送门 不错的莫队练手题 块数就直接取sqrt(n) 对所有询问进行排序 排序第一关键词:l所在第几块,第二关键词:r的位置 考虑Ai不大,暴力开数组 add时如果加之后 ...
- 【luogu P3901 数列找不同】 题解
对于区间查询的问题,提供一种思路: 莫队. 莫队是处理区间问题的乱搞神器,尤其是对于离线查询问题,当然也可以做在线查询,比如带修莫队. 对于有的题,莫队是乱搞骗分,而在某些地方,莫队是正解. 这道题来 ...
- 洛谷P3901 数列找不同(莫队水题)
重温下手感,判断区间是否全是不同的数字有两种做法,一个长度为len的区间不同的数字,参见HH的项链,一种是区间众数,参见蒲公英,是水题没错了.明天搞数据库,然后继续自己的gre和训练计划 #inclu ...
- Different Integers(牛客多校第一场+莫队做法)
题目链接:https://www.nowcoder.com/acm/contest/139/J 题目: 题意:给你n个数,q次查询,对于每次查询得l,r,求1~l和r~n元素得种类. 莫队思路:1.将 ...
随机推荐
- 自己动手做AI:Google AIY开发工具包解析
2018年国际消费性电子展(CES)上,最明显的一个趋势是Amazon与Google的语音技术进驻战,如AmazonAlexa进驻到Acer笔电内,Google Assist进驻到KIA汽车内,其他如 ...
- docker简单使用+django+uwsgi+nginx项目部署
使用docker 搭建 centos7 环境: 主机环境:windows 10专业版 一.安装docker Hub.docker.com官网下载 docker for windows 安装完成后,任务 ...
- 曾经我是一个只会excel的数据分析师,直到我遇到了……
我是一个数据分析师. 准确来说我是一个当年只会excel数据透视表,就天不怕地不怕地来当数据分析师的人.当年的某一天,我的老板Q我: 小刘啊,我小姨子给了我一个全国市委书记的名单,你帮我看看,有什么规 ...
- Android源码项目目录结构
src: 存放java代码 gen: 存放自动生成文件的. R.java 存放res文件夹下对应资源的id project.properties: 指定当前工程采用的开发工具包的版本 libs: 当前 ...
- Microsoft Orleans 之简介
Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...
- purcell的emacs配置中的自动补全功能开启
标记一下,原文参看purcell的emacs配置中的自动补全功能开启 修改init-auto-complete.el文件 ;;(setq-default ac-expand-on-auto-compl ...
- python基础(一)简单入门
一.第一个python程序 1.交互式编程 直接在命令行里面输入python即可进入python交互式命令行,linux下一样: 在 python 提示符中输入以下文本信息,然后按 Enter 键查看 ...
- 【vue】父组件主动调用子组件 /// 非父子组件传值
一 父组件主动调用子组件: 注意:在父组件使用子组件的标签上注入ref属性,例如: <div id="home"> <v-header ref="he ...
- LeetCode 671. Second Minimum Node In a Binary Tree
Given a non-empty special binary tree consisting of nodes with the non-negative value, where each no ...
- 我为什么鼓励工程师写blog
文/JoeyChen 工程师该怎样才能突破自己的能力瓶颈?写 blog! 工程师该怎样精进自己在职涯上所需要的能力?写 blog! 工程师该怎样才能保持学习与成长的动能?写 blog! 工程师该怎样才 ...