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. Codeforces 839B - Game of the Rows

    839B - Game of the Rows 思路:先放4个的,然后再放2个的,最后再放1个的. 代码: #include<bits/stdc++.h> using namespace ...

  2. Python 爬虫-Scrapy框架基本使用

    2017-08-01  22:39:50 一.Scrapy爬虫的基本命令 Scrapy是为持续运行设计的专业爬虫框架,提供操作的Scrapy命令行. Scrapy命令行格式 Scrapy常用命令 采用 ...

  3. Javascript 面向对象-继承

    JavaScript虽然不是面向对象的语言,但是我们通过构造可以让其支持面向对象,从而实现继承.重写等面向对象的特性.具体代码如下: //创建类Person function Person(age,n ...

  4. 为什么需要API网关?

    目录 0:00 微服务与网关(Microservices & API Gateways) 大家好,我叫Macro,今天我们谈论有关微服务和网关的话题.我是Mashape的CTO,也同时是开源网 ...

  5. windows下python检查文件是否被其它文件打开

    windows下python检查文件是否被其它文件打开.md 有时候我们需要能够判断一个文件是否正在被其它文件访问,几乎不可避免的要调用操作系统接口 from ctypes import cdll i ...

  6. Java基础-IO流(13)

    IO流用来处理设备之间的数据传输.可以实现文件复制,上传文件和下载文件. Jdk提供的流继承了四大类:InputStream(字节输入流),OutputStream(字节输出流),Reader(字符输 ...

  7. 【转】Vue.js特点

    作为一名Vue.js的忠实用户,我想有必要写点文章来歌颂这一门美好的语言了,我给它的总体评价是“简单却不失优雅,小巧而不乏大匠”,下面将围绕这句话给大家介绍Vue.js,希望能够激发你对Vue.js的 ...

  8. in_array的效率

    in_array函数是个糟糕的选择.应该尽量用isset函数或array_key_exists函数来替代 .in_array函数的复杂度是O(n),而isset函数的复杂度是O(1) isset函数是 ...

  9. 清除mac出现的.DS_Store文件

    一.什么是.DS_Store文件 在 Mac OS X 系统下,大部分文件夹中都包含 .DS_Store 隐藏文件,这里保存着针对这个目录的特殊信息和设置配置,例如查看方式.图标大小以及这个目录的一些 ...

  10. PHP:第一章——PHP中的算术运算符/递增、递减运算符/赋值运算符

    算术运算符 //$a=10; $b=5; //取反: //echo -$a;//输出:-10: //加法: //echo $a+$b;//输出:15 //减法: //echo $a-$b;//输出:5 ...