zoukankan      html  css  js  c++  java
  • 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行,每行两个整数 fr,to,表示对S 的
    子串S[fr…to]的一次询问。注意:S的最左端的数字的位置序号为 1;例如S为213567,则S[1]为 2,S[1…3]为 2
    13。N,M<=100000,P为素数

    【输出格式】

    输出M行,每行一个整数,第 i行是第 i个询问的答案。

    【输入样例】

    11
    121121
    3
    1 6
    1 5
    1 4

    【输出样例】

    5
    3
    2

    【样例解释】

    第一个询问问的是整个串,满足条件的子串分别有:121121,2112,11,121,121。

    【数据规模】

    N,M<=100000

    正解:莫队算法+特判

    解题报告:有一个结论比较鬼,就是如果在一串数中,如果从第一位到当前位和第一位到

    第k位模一个数(非2和5)相等,那么第k位到当前位模这个数为0,知道这个结论之后我们

    就可以用莫队暴力分块了,然后对于2和5就直接记前缀和统计。

     1 #include <iostream>
     2 #include <iomanip>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <cstring>
     9 #include <map>
    10 #define File(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    11 #define RG register
    12 #define ull unsigned long long
    13 const int N = 150000;
    14  
    15 using namespace std;
    16  
    17 map <ull,ull> Map;
    18  
    19 ull gi(){
    20     char ch=getchar();ull x=0;
    21     while(ch<'0' || ch>'9')ch=getchar();
    22     while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
    23     return x;
    24 }
    25  
    26 char ch[N];
    27 ull yu[N],rt[N],jl[N],da[N],xh[N],sum[N];
    28 ull sq;
    29  
    30 struct date{
    31     int l,r,i;
    32     bool operator < (const date &a) const{
    33         if (a.l/sq==l/sq) return a.r>r;
    34         return a.l/sq>l/sq;
    35     }
    36 }f[N],t[N];
    37  
    38 bool cmp(const date &a,const date &b){
    39     if (a.r==b.r) return a.l<b.l;
    40     return a.r<b.r;
    41 }
    42  
    43 void put(ull x)
    44 {
    45     int num = 0; char c[20];
    46     while(x) c[++num] = (x%10)+48, x /= 10;
    47     while(num) putchar(c[num--]);
    48     putchar('
    ');
    49 }
    50  
    51 int main(){
    52     File("number");
    53     ull p=gi();scanf("%s",ch);
    54     int q=gi();RG int i,l,r;ull ans=0;ull j;
    55     int h=strlen(ch);sq=sqrt(h*1.0);
    56     for (i=1; i<=q; i++) f[i]=(date){gi(),gi(),i};
    57     if (p!=2 && p!=5){
    58         for (i=1; i<=q; i++) f[i].r++;
    59         j=1;yu[h+1]=0;
    60         for (i=h-1; i>=0; i--){
    61             j=j*10%p;
    62             rt[i+1]=yu[i+1]=(yu[i+2]+(ch[i]-'0')*j)%p;
    63         }h++;
    64         sort(rt+1,rt+h+1);
    65         sort(f+1,f+q+1);
    66         for (i=1; i<=h; i++) Map[rt[i]]=i;
    67         for (i=1; i<=h; i++) yu[i]=Map[yu[i]];
    68         l=f[1].l,r=l-1;ans=0;
    69         for (i=1; i<=q; i++){
    70             while(l>f[i].l) ans+=jl[yu[--l]]++;
    71             while(r<f[i].r) ans+=jl[yu[++r]]++;
    72             while(l<f[i].l) ans-=--jl[yu[l++]];
    73             while(r>f[i].r) ans-=--jl[yu[r--]];
    74             da[f[i].i]=ans;
    75         }
    76     }else{
    77             for (i=1; i<=h; i++){
    78                 yu[i]=(ch[i-1]-'0')%p;
    79                 xh[i]=xh[i-1]+(yu[i]==0?1:0);
    80                 sum[i]=sum[i-1]+(yu[i]==0?i:0);
    81             }
    82             for (i=1; i<=q; i++)
    83                 da[i]=sum[f[i].r]-sum[f[i].l-1]-(f[i].l-1)*(xh[f[i].r]-xh[f[i].l-1]);
    84         }
    85     for (i=1; i<=q; i++)
    86             if (da[i]) put(da[i]);
    87             else printf("0
    ");
    88         return 0;
    89 }
  • 相关阅读:
    动态代理,反射的用途及实现
    谈一谈web.xml中的context-param和init-param
    后端程序员需要了解的前端知识(持续更新中)
    angularJS要点记录,$location,$http等等
    HTTP1.0和HTTP2.0的区别,以及HTTP和HTTPS的区别
    浅谈Fork/Join框架
    ConcurrentHashMap 的工作原理及源码分析,如何统计所有的元素个数
    HTTP协议常见的状态码
    图解HTTP,状态码,TCP、UDP等网络协议相关总结(持续更新)
    jmeter(五)JDBC Request
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6380086.html
Copyright © 2011-2022 走看看