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

    Output

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

    Sample Input

    11
    121121
    3
    1 6
    1 5
    1 4

    Sample Output

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

    HINT

     2016.4.19新加数据一组

     
    题解:
    把后缀模p的数搞出来离散化一下就可以上莫队了
    注意p=2或p=5
    code:
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 typedef long long int64;
      8 char ch;
      9 bool ok;
     10 void read(int &x){
     11     ok=0;
     12     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     13     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     14     if (ok) x=-x;
     15 }
     16 void read(int64 &x){
     17     ok=0;
     18     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     19     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     20     if (ok) x=-x;
     21 }
     22 const int maxn=100005;
     23 char s[maxn];
     24 int n,q,sn,x,y,bel[maxn],tot,cnt[maxn];
     25 int64 mod,a[maxn],ans[maxn],res,pw[maxn],list[maxn];
     26 struct Querys{
     27     int l,r,id;
     28     void init(int i){read(l),read(r),l=n-l+1,r=n-r+1,swap(l,r),l--,/*cout<<"FFFF "<<l<<' '<<r<<endl,*/id=i;}
     29 }querys[maxn];
     30 bool cmp(const Querys &a,const Querys &b){return bel[a.l]<bel[b.l]||(bel[a.l]==bel[b.l]&&bel[a.r]<bel[b.r]);}
     31 void modify(int col,int op){
     32     if (op==1) /*cout<<res<<' '<<col<<' '<<cnt[col]<<endl,*/res+=cnt[col],cnt[col]++;
     33     else cnt[col]--,res-=cnt[col];
     34 }
     35 void work(){
     36     int l=0,r=0; cnt[a[0]]=1,res=0;
     37     for (int i=1;i<=q;i++){
     38         for (;l<querys[i].l;l++) modify(a[l],-1);
     39         for (;l>querys[i].l;l--) modify(a[l-1],1);
     40         for (;r<querys[i].r;r++) modify(a[r+1],1);
     41 //      cout<<"res="<<res<<endl;
     42         for (;r>querys[i].r;r--) modify(a[r],-1);
     43         ans[querys[i].id]=res;
     44     }
     45 }
     46 int cnt2[maxn],cnt5[maxn];
     47 int64 ans2[maxn],ans5[maxn];
     48 int main(){
     49     read(mod);
     50     if (mod==2){
     51         scanf("%s",s+1),n=strlen(s+1);
     52         for (int i=1;i<=n;i++){
     53             cnt2[i]=cnt2[i-1],ans2[i]=ans2[i-1];
     54             if ((s[i]-'0')%2==0) cnt2[i]++,ans2[i]+=i;
     55         }
     56         for (read(q);q;q--){
     57             read(x),read(y);
     58             printf("%lld
    ",ans2[y]-1LL*(cnt2[y]-cnt2[x-1])*(x-1)-ans2[x-1]);
     59         }
     60     }
     61     else if (mod==5){
     62         scanf("%s",s+1),n=strlen(s+1);
     63         for (int i=1;i<=n;i++){
     64             cnt5[i]=cnt5[i-1],ans5[i]=ans5[i-1];
     65             if ((s[i]-'0')%5==0) cnt5[i]++,ans5[i]+=i;
     66         }
     67         for (read(q);q;q--){
     68             read(x),read(y);
     69             printf("%lld
    ",ans5[y]-1LL*(cnt5[y]-cnt5[x-1])*(x-1)-ans5[x-1]);
     70         }   
     71     }
     72     else{
     73         scanf("%s",s+1),n=strlen(s+1),sn=sqrt(n);
     74         for (int i=1,j=n;i<j;i++,j--) swap(s[i],s[j]);
     75         for (int i=0;i<=n;i++) bel[i]=i/sn;
     76     //  for (int i=0;i<=n;i++) cout<<i<<' ';cout<<endl;
     77     //  for (int i=0;i<=n;i++) cout<<bel[i]<<' ';cout<<endl;
     78         pw[0]=1;
     79         for (int i=1;i<=n;i++) pw[i]=1LL*pw[i-1]*10%mod;
     80         for (int i=1;i<=n;i++) a[i]=(a[i-1]+1LL*(s[i]-'0')*pw[i-1]%mod)%mod;
     81         for (int i=0;i<=n;i++) list[++tot]=a[i];
     82         sort(list+1,list+tot+1),tot=unique(list+1,list+tot+1)-list-1;
     83 //      for (int i=0;i<=n;i++) cout<<a[i]<<' ';cout<<endl;
     84         for (int i=0;i<=n;i++) a[i]=lower_bound(list+1,list+tot+1,a[i])-list;
     85 //      for (int i=0;i<=n;i++) cout<<a[i]<<' ';cout<<endl;
     86         read(q);
     87     //  cout<<q<<endl;
     88         for (int i=1;i<=q;i++) querys[i].init(i);
     89 //      for (int i=1;i<=q;i++) cout<<querys[i].l<<' '<<querys[i].r<<' '<<querys[i].id<<endl;
     90         sort(querys+1,querys+q+1,cmp);
     91         work();
     92         for (int i=1;i<=q;i++) printf("%lld
    ",ans[i]);
     93     }
     94     return 0;
     95 }
     96 /*
     97 11
     98 121121
     99 3
    100 1 6
    101 1 5
    102 1 4
    103 */
  • 相关阅读:
    如何提高沟通能力?
    如何做到科学决策?推荐你看这本《决策必读12篇》
    领导者如何让员工真心服从自己?
    MBA看什么书,MBA教材书目推荐
    有关战略管理的书,哪本最值得推荐?
    市场营销必看书籍推荐
    P1208 混合牛奶题解
    P5019 铺设道路题解
    P1728 陶陶摘苹果题解
    P1106 删数问题题解
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5416849.html
Copyright © 2020-2023  润新知