【bzoj4542】[Hnoi2016]大数

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 using namespace std;
  8
  9 typedef long long LL;
 10
 11 #define N 100010
 12
 13 struct Node
 14 {
 15     LL val;
 16     int id;
 17 }md[N];
 18
 19 struct data
 20 {
 21     int l,r,id;
 22 }ask[N];
 23
 24 char s[N];
 25
 26 LL c[N],d[N],h[N];
 27 LL a[N];
 28
 29 LL p;
 30 int m,n;
 31 int l,r;
 32
 33 int len,K;
 34
 35 int cmp(Node aa,Node bb)
 36 {
 37     return aa.val<bb.val;
 38 }
 39
 40 int cmp2(data aa,data bb)
 41 {
 42     return aa.l/K==bb.l/K ? aa.r<bb.r : aa.l<bb.l;
 43 }
 44
 45 void work()
 46 {
 47     for (int i=1;i<=len;i++)
 48     {
 49         d[i]=d[i-1]+((s[i-1]-‘0‘)%p ? 0 : i);
 50         c[i]=c[i-1]+((s[i-1]-‘0‘)%p==0);
 51     }
 52     scanf("%d",&m);
 53     while (m--)
 54     {
 55         scanf("%d%d",&l,&r);
 56         printf("%lld\n",d[r]-d[l-1]-(c[r]-c[l-1])*(l-1));
 57     }
 58 }
 59
 60 int main()
 61 {
 62     scanf("%lld",&p);
 63     scanf("%s",s);
 64     len=strlen(s);
 65     K=sqrt(len)+1;
 66     if (p==2 || p==5)
 67     {
 68         work();
 69         return 0;
 70     }
 71     LL res=1;
 72     for (int i=len-1;i>=0;i--)
 73     {
 74         md[i].val=(md[i+1].val+(s[i]-‘0‘)*res)%p;
 75         md[i].id=i;
 76         res=res*10%p;
 77     }
 78     md[len].id=len;
 79     sort(md,md+len+1,cmp);
 80     res=0;
 81     for (int i=0;i<=len;i++)
 82     {
 83         if (i && md[i].val!=md[i-1].val)
 84             res++;
 85         h[md[i].id]=res;
 86     }
 87     scanf("%d",&m);
 88     for (int i=0;i<=m;i++)
 89     {
 90         scanf("%d%d",&ask[i].l,&ask[i].r);
 91         ask[i].l--;
 92         ask[i].id=i;
 93     }
 94     sort(ask,ask+m,cmp2);
 95     int L(0),R(-1);
 96     res=0;
 97     for (int i=0;i<m;i++)
 98     {
 99         while (R<ask[i].r)
100             res+=c[h[++R]]++;
101         while (R>ask[i].r)
102             res-=--c[h[R--]];
103         while (L>ask[i].l)
104             res+=c[h[--L]]++;
105         while (L<ask[i].l)
106             res-=--c[h[L++]];
107         a[ask[i].id]=res;
108     }
109     for (int i=0;i<m;i++)
110         printf("%lld\n",a[i]);
111     return 0;
112 }
时间: 2025-01-12 15:39:25

【bzoj4542】[Hnoi2016]大数的相关文章

BZOJ4542 [HNOI2016] 大数

[问题描述] 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345 .小B还有一个素数P.现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也 是P 的倍数).例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007:显然0077的子串007有6个子串都是素 数7的倍数. [输入格式] 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数

[BZOJ4542] [Hnoi2016] 大数 (莫队)

Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也是P 的倍数).例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007:显然0077的子串007有6个子串都是素数7的倍数. Input 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数

bzoj4542: [Hnoi2016]大数(莫队)

这题...离散化...$N$和$n$搞错了...查了$2h$...QAQ 考虑$s[l...r]$,可以由两个后缀$suf[l]-suf[r+1]$得到$s[l...r]$代表的数乘$10^k$得到的结果,如果$p$不为$2$或$5$,即$gcd(p, 10^k)=1$,那么显然$s[l...r]$乘$10^k$模$p$为$0$的话,$s[l...r]$模p也为$0$,所以我们就可以变成询问$[l,r+1]$里有几个相同的后缀了. 如果$p$为$2$或$5$的话,我们还得判断这个数的个位是否是$

【莫队】bzoj4542: [Hnoi2016]大数

挺有意思的,可以仔细体味一下的题:看白了就是莫队板子. Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也是P 的倍数).例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007:显然0077的子串007有6个子串都是素数7的倍数. Input 第一行一个整数:P.第二行

【BZOJ4542】[Hnoi2016]大数 莫队

[BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个询问求 S 的一个子串中有多少子串是 P 的倍数(0 也是P 的倍数).例如 S为0077时,其子串 007有6个子串:0,0,7,00,07,007:显然0077的子串007有6个子串都是素数7的倍数. Input 第一行一个整数:P.第二行一个串:S

[BZOJ4542] [JZYZOJ2014][Hnoi2016] 大数(莫队+离散化)

正经题解在最下面 http://blog.csdn.net/qq_32739495/article/details/51286548 写的时候看了大神的题解[就是上面那个网址],看到下面这段话 观察题目,发现一串数s(l~r)整除p满足s(l~n-1)%p==s(r+1~n-1)%p 但p值为2或5不满足这个性质需要特判(不过数据中好像没有,于是笔者没写,有兴趣的可以自己去写写......) 然后问题转化为求一段区间中有几对相等的f值. 看到这里,我感觉豁然开朗,完全忽视了离散化的要求,我以为把

【bzoj5452】[Hnoi2016]大数(莫队)

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4542 首先若p=2,5则这题就是道傻逼题,前缀和搞一下没了.如果p为其他质数,那么可以这么处理: 我们先预处理出数组num[i]表示原串第i~n位表示的数模p的余数,那么第l~r位表示的数模p的余数为(num[l]-num[r+1])/10^(n-r),因为10^(n-r)与p互质,所以若num[l]=num[r+1],则第l~r位表示的数是p的倍数.于是莫队一下就好了. 代码: #

【BZOJ】4542: [Hnoi2016]大数

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4542 给定一个由数字构成的字符串${S_{1,2,3,...,n}}$,一个正素数$P$,每次询问给定一对$l$,$r$求: $${\sum_{l=1}^{n}\sum_{r=i}^{n}\left [ \sum _{i=l}^{r}S[i]*10^{r-i} \,\,\,\,MOD\,\,\,\,P=0 \right ]}$$ 即以位置$x$开头的后缀的数字$%P$之后的值为$val[

4542: [Hnoi2016]大数|莫队

HN一天考两个莫队是什么鬼..或者说莫队不是正确的姿势..? 考虑已经知道了l..r的答案新添入r+1如何更新当前答案 需要先预处理出后缀modp的值bi,假设子序列l..r模p的值为x 那么x?10r?l+b[r]=b[l] 然后就可以直接莫队统计了 模数为2或5的时候要特判一下 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cs