BZOJ.4542.[HNOI2016]大数(莫队)
大数除法是很麻烦的,考虑能不能将其条件化简
一段区间[l,r]|p,即num[l,r]|p,类似前缀,记后缀suf[i]表示[i,n]的这段区间代表的数字
于是有 suf[l]-suf[r+1]|p -> (suf[l]-suf[r+1])%p = 0 -> suf[l] ≡suf[r+1] (mod p)
即若suf[r+1]%p = suf[l]%p,则num[l,r]|p
于是我们可以把范围控制在p以内,查找是否有%p相等的区间 -> 莫队
即小Z的袜子
这样的实际意义是 \((suf[l]-suf[r+1])*10^{n-r}%p = 0\)
后面有个10的幂,如果n-r>0 对于p(p|10)显然无论[l,r]是什么都会满足条件
于是p=2,5时要换一种判断方式。显然若有一位A[i]满足A[i]|p,则之前的Aj都可以以它为结尾并对答案做出贡献
若数列(都加l-1)a,b,c,d,e中,A[a,d,e]|p,则答案为e+d+a-3*(l-1)
这个在线做就可以了 (另外有人知道这个我莫队为什么不对吗。。)
另外要注意p范围不定,要对出现的余数离散化
然后参数p和模数p会重着 要注意!
要注意会有A[n+1],离散化要注意这个变量默认0!
另外p<P时特判为什么不对。。
洛谷数据真的水。。在BZOJ被longlong什么的各种坑。
#include <cmath>
#include <cctype>
#include <cstdio>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=2e5+5,P=1e6;
int n,m,size,tm[P+5],Cnt;
LL p/*LL!*/,A[N],suf[N],ref[N],Now,Ans[N],sum[N],num[N];
struct Ask
{
int l,r,id;
bool operator <(const Ask &a)const {
return l/size==a.l/size?r<a.r:l/size<a.l/size;
}
}q[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void Update(int pos,int delta){
if(!(A[pos]%p)) Now+=delta*pos, Cnt+=delta;
}
void Spec()
{
for(int i=1; i<=n; ++i)
if(A[i]%p) sum[i]=sum[i-1],num[i]=num[i-1];
else sum[i]=sum[i-1]+i,num[i]=num[i-1]+1;
for(LL l,r,i=1; i<=m; ++i)
l=read(),r=read(), printf("%lld\n",sum[r]-sum[l-1]-(num[r]-num[l-1])*(l-1));
// for(int l=1,r=0,i=1; i<=m; ++i)
// {
// while(l<q[i].l) Update(l,-1),++l;
// while(l>q[i].l) --l,Update(l,1);
// while(r<q[i].r) ++r,Update(r,1);
// while(r>q[i].r) Update(r,-1),--r;
// Ans[q[i].id]=Now-Cnt*(q[i].l-1);
// }
}
inline void Add(int p){
if(!p) return;
Now+=tm[p], ++tm[p];
// if(++tm[p]>1) Now+=tm[p]-1;//不要判什么tm[]>1之类满足才更新答案,因为tm[]在中间过程是可以存在负数的
}
inline void Subd(int p){
if(!p) return;
--tm[p], Now-=tm[p];
// if(--tm[p]) Now-=tm[p];//这一写法效果一样(因为只判了!=0) 但不能这么写
}
void Normal()
{
for(int l=1,r=0,i=1; i<=m; ++i)
{
while(l<q[i].l) Subd(suf[l++]);
while(l>q[i].l) Add(suf[--l]);
while(r<q[i].r) Add(suf[++r]);
while(r>q[i].r) Subd(suf[r--]);
Ans[q[i].id]=Now;
}
}
int Find(int x,int r)
{
int l=1,mid;
while(l<r)
if(ref[mid=l+r>>1]>=x) r=mid;
else l=mid+1;
return l;
}
void Discrete()
{
for(int i=1; i<=n; ++i) ref[i]=suf[i];
std::sort(ref+1,ref+1+n);
int cnt=1;
for(int i=2; i<=n; ++i)
if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
for(int i=1; i<=n; ++i) suf[i]=Find(suf[i],cnt);
suf[n+1]=ref[1]?0:1;
}
int main()
{
scanf("%lld",&p);
char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);A[++n]=c-'0',c=gc());
m=read(), size=sqrt(n);
if(p==2||p==5) {Spec(); return 0;}
for(int i=1; i<=m; ++i)
q[i].l=read(),q[i].r=read()+1,q[i].id=i;//q:r+1
LL pw10=1;//longlong!
for(int i=n; i; --i)
suf[i]=(A[i]*pw10%p+suf[i+1])%p, pw10=pw10*10%p;
// if(p>P) Discrete();//这个if?
Discrete();
std::sort(q+1,q+1+m);
// if(p==2||p==5) Spec();
// else Normal();
Normal();
for(int i=1; i<=m; ++i) printf("%lld\n",Ans[i]);
return 0;
}
BZOJ.4542.[HNOI2016]大数(莫队)的更多相关文章
- bzoj 4542: [Hnoi2016]大数 (莫队)
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- 【BZOJ4542】[Hnoi2016]大数 莫队
[BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个 ...
- BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]
4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...
- [BZOJ4542] [Hnoi2016] 大数 (莫队)
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- BZOJ 4540 [Hnoi2016]序列 | 莫队 详细题解
传送门 BZOJ 4540 题解 --怎么说呢--本来想写线段树+矩阵乘法的-- --但是嘛--yali的机房太热了--困--写不出来-- 于是弃疗,写起了莫队.(但是我连莫队都想不出来!) 首先用单 ...
- bzoj4542 [Hnoi2016]大数 莫队+同余
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...
- bzoj 4542: [Hnoi2016]大数
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345 小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- 洛谷P3245 [HNOI2016]大数(莫队)
题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ...
随机推荐
- python脚本发送邮件
#!/usr/bin/python #_*_ coding:utf-8 _*_ from email.MIMEText import MIMEText from email.MIMEMultipart ...
- 网络抓包 Fiddler
1. Fiddler 抓包简介 Fiddler是通过改写HTTP代理,让数据从它那通过,来监控并且截取到数据.当然Fiddler很屌,在打开它的那一瞬间,它就已经设置好了浏览器的代理了.当你关闭的时候 ...
- oem 重建
OracleDBControl启动失败to local from URL=http://your-url.co 方法: emca -deconfig dbcontrol db -repos d ...
- 路由器中继(repeater)模式 和 AP+WDS模式区别?
理论上的 中继(repeater)模式, 只有连接的最后一个才会有信号发出,中间的连接节点是没有信号发出的. AP+WDS模式:就是每一个路由都有信号发出,可以进行信号的全方位覆盖.
- centos 编译安装PHP5.4
2013年12月29日 19:52:30 已经安装好Apache 2.4 php版本 5.4 ./configure --prefix=/usr/local/lamp/php --with-apxs2 ...
- 使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL
有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...
- MySQL数据库排序选择的作用和该如何选择编码格式
前言:在创建数据库的时候,会有这样一个选项->排序规则,平时在创建数据库的时候并没有注意,只是选择了默认,也没感觉有什么问题,今天看到这个突然好奇起来,所以看了一些资料做了以下的一些总结,若有错 ...
- LeetCode(32):最长有效括号
Hard! 题目描述: 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 ...
- C++ code:More Loop Designs
1 逻辑判断 对于逻辑判断问题,一般都要考虑全部的可能性,然后从这些可能性中按条件逐一排查,直到最后获得某个结论. [百钱买百鸡问题] 问题描述: 雄鸡(cock)7元一只,母鸡(hen)5元一只, ...
- Elasticsearch创建索引和映射结构详解
前言 这篇文章详细介绍了如何创建索引和某个类型的映射. 下文中[address]指代elasticsearch服务器访问地址(http://localhost:9200). 1 创建索引 ...