Luogu 3245 大数

  • 开始就想 \(10\) 进制 \(hash\) ,\(Hash(r)\equiv Hash(l-1)\cdot 10^{r-l+1}\) ,感觉没什么美妙的性质啊...
  • 然后把 \(hash\) 换个方向,先加低位,再加高位,就成了 \(\frac {Hash(l)-Hash(r+1)} {10^{n-r}}\equiv 0\) ,似乎,就很美妙了?
  • 当 \(P\not=2,5\) 时,下面的分母有逆元,那么只能是 \(Hash(l)\equiv Hash(r+1)\) ,就变成了在一段区间内问相同元素的对数,离散化之后,用莫队可以解决.
  • 当 \(P=2,5\) 时,一段区间内仅有以 \(P,0\) 结尾的串符合条件,计数相当简单.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
fh=-1,jp=getchar();
while (jp>='0'&&jp<='9')
out=out*10+jp-'0',jp=getchar();
return out*fh;
}
const int MAXN=1e5+10;
int n,m,P;
inline int add(int a,int b)
{
return (a + b) % P;
}
inline int mul(int a,int b)
{
return 1LL * a * b % P;
}
struct query
{
int l,r,id,bel;
bool operator < (const query &rhs) const
{
if(bel!=rhs.bel)
return bel<rhs.bel;
if(r!=rhs.r)
return r<rhs.r;
return l<rhs.l;
}
}q[MAXN];
char buf[MAXN];
int Hash[MAXN],cp[MAXN];
int cnt[MAXN];
ll ans[MAXN],res;
void add(int x)
{
res+=cnt[Hash[x]];
++cnt[Hash[x]];
}
void rem(int x)
{
--cnt[Hash[x]];
res-=cnt[Hash[x]];
}
int sumcnt[MAXN],sumpos[MAXN];
void solve_spj()
{
for(int i=1;i<=n;++i)
{
if(buf[i]-'0'==0 || buf[i]-'0'==P)
sumcnt[i]=1,sumpos[i]=i;
sumcnt[i]+=sumcnt[i-1];
sumpos[i]+=sumpos[i-1];
}
m=read();
for(int i=1;i<=m;++i)
{
int l=read(),r=read();
ll cntsum=sumcnt[r]-sumcnt[l-1],possum=sumpos[r]-sumpos[l-1];
ll res=possum-1LL*(l-1)*cntsum;
printf("%lld\n",res);
}
}
int main()
{
P=read();
scanf("%s",buf+1);
n=strlen(buf+1);
if(P==2 || P==5)
{
solve_spj();
return 0;
}
int pow10=1;
for(int i=n;i>=1;--i)
{
cp[i]=Hash[i]=add(Hash[i+1],mul(buf[i]-'0',pow10));
pow10=mul(pow10,10);
}
++n;//0
sort(cp+1,cp+1+n);
int tot=unique(cp+1,cp+1+n)-cp-1;
for(int i=1;i<=n;++i)
Hash[i]=lower_bound(cp+1,cp+1+tot,Hash[i])-cp;
m=read();
int BlockSize=sqrt(m);
for(int i=1;i<=m;++i)
{
q[i].l=read();
q[i].r=read();
q[i].id=i;
q[i].bel=q[i].l/BlockSize;
}
sort(q+1,q+1+m);
int L=1,R=0;
for(int i=1;i<=m;++i)
{
int l=q[i].l,r=q[i].r;
++r;
if(l==r)
continue;
while(R<r)
add(++R);
while(L<l)
rem(L++);
while(L>l)
add(--L);
while(R>r)
rem(R--);
ans[q[i].id]=res;
}
for(int i=1;i<=m;++i)
printf("%lld\n",ans[i]);
return 0;
}

Luogu 3245 大数的更多相关文章

  1. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  2. luogu P3245 [HNOI2016]大数

    传送门 \(HNOI2019\)前最后一题了qwq 这题要分情况,如果\(p=2\)或\(5\),那么只要区间内最后一个数字是\(p\)的倍数就好了,这个可以莫队,也有更优秀的做法.莫队做法可以看代码 ...

  3. Luogu 3332 [ZJOI2013]K大数查询

    BZOJ 3110 很早就想写的试炼场题. 不会整体二分啊呜呜呜,只能写写树套树. 有一个trick就是外层使用一个权值线段树,把位置作为下标的线段树放在内层,这样子的话我们在查询$k$大的时候就可以 ...

  4. 【Luogu】P3332K大数查询(树套树)

    题目链接 这题我费尽心思不用标记永久化终于卡过去了qwq 权值线段树下面套一个区间线段树.然后乱搞搞即可. // luogu-judger-enable-o2 #include<cstdio&g ...

  5. [HNOI 2016]大数

    Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...

  6. 【树状数组套主席树】带修改区间K大数

    P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+ ...

  7. [ZJJOI2013]K大数查询 整体二分

    [ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...

  8. 洛谷P1050 循环【java大数】

    题目:https://www.luogu.org/problemnew/show/P1050 题意:给定一个数$n$,问$n$的幂次的最低$k$位的循环节是多少. 思路:这真是我做过最难的java大数 ...

  9. 洛谷P1080 国王游戏【大数】【贪心】

    题目:https://www.luogu.org/problemnew/show/P1080 题意: 一个国王和n个大臣,每个人左右手上都有一个数值. 现在将国王排在队首,将大臣进行排序.每个大臣的值 ...

随机推荐

  1. logback的使用和logback.xml详解[转]

    一.logback的介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch.它当前分为下面下个模块: logback-core:其它两 ...

  2. 一个纯净的webpack4+angular5脚手架

    该篇主要是结合刚发布不久的webpack4,搭建一个非cli的angular5的脚手架demo,主要分为以下几个方面阐述下脚手架结构: # 脚手架基础架构(根据angular5的新规范) /** * ...

  3. 雷林鹏分享:C# 索引器(Indexer)

    C# 索引器(Indexer) 索引器(Indexer) 允许一个对象可以像数组一样被索引.当您为类定义一个索引器时,该类的行为就会像一个 虚拟数组(virtual array) 一样.您可以使用数组 ...

  4. 多个 CancellationTokenSource 复合(组合) 或 C# 使用 CancellationTokenSource 终止线程

    https://www.cnblogs.com/luohengstudy/p/5623451.html https://www.cnblogs.com/wlzhang/p/4604471.html

  5. python模块——random模块(简单验证码实现)

    实现一个简单的验证码生成器 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = "loki" # Usage: 验证 ...

  6. 『cs231n』线性分类器损失函数

    代码部分 SVM损失函数 & SoftMax损失函数: 注意一下softmax损失的用法: SVM损失函数: import numpy as np def L_i(x, y, W): ''' ...

  7. 绝对干货!!css3字体图标—丰富的阿里图标库iconfont的使用详解

    在移动端Web项目开发中,我们往往需要用到一些小图标,比如搜索,返回,小菜单,小箭头等等..这如果还用切图你就OUT了.. 而这时CSS3提供的字体图标无疑是我们最好的选择,它就像字体一样,可以设置大 ...

  8. .split(",", -1);和.split(",")的区别

    .split(",", -1);和.split(",")的区别在于://eg:String a="河南省,,金水区".//a.split(& ...

  9. exec可以用来执行语句的

    set @sql='select * from '+@table print @sql exec(@sql)

  10. POJ 3481 treap

    这是利用treap写的二叉排序树,只要理解其中旋转能够改变树的左右子树平衡度,即高度之差,差不多就能掌握treap树的要领了. 相对于其他高级BST,treap树实现应该算最简单了,利用的是随机树产生 ...