• [BZOJ4542][HNOI2016]大数(莫队)


    4542: [Hnoi2016]大数

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1691  Solved: 589
    [Submit][Status][Discuss]

    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新加数据一组

    代码用时:1h

    10W级的数据跑莫队比较正常吧。注意特判P==2 || P==5的情况(只需要判断个位数即可)。

    WA了两次,struct D中x变量应该是long long的。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=l; i<=r; i++)
     6 typedef long long ll;
     7 using namespace std;
     8 
     9 const int N=200100;
    10 int n,m,x,y,cnt,bl[N],num[N],c[N];
    11 ll P,ans,res[N];
    12 char S[N];
    13 struct D{ ll x; int y; }s[N];
    14 struct T{ int l,r,id; }a[N];
    15 
    16 bool cmp(D a,D b){ return a.x<b.x; }
    17 bool cmp1(T a,T b){ return (bl[a.l]==bl[b.l]) ? a.r<b.r : bl[a.l]<bl[b.l]; }
    18 void work(int x,int k){
    19     if (k==1) ans+=num[c[x]],num[c[x]]++;
    20             else num[c[x]]--,ans-=num[c[x]];
    21 }
    22 
    23 void solve(){
    24     rep(i,1,n){
    25         s[i]=s[i-1];
    26         if (!((S[i]-'0')%P)) s[i].x+=i,s[i].y++;
    27     }
    28     while (m--) scanf("%d%d",&x,&y),printf("%lld
    ",s[y].x-s[x-1].x-1ll*(x-1)*(s[y].y-s[x-1].y));
    29 }
    30 
    31 int main(){
    32     freopen("bzoj4542.in","r",stdin);
    33     freopen("bzoj4542.out","w",stdout);
    34     scanf("%lld",&P); scanf("%s%d",S+1,&m);
    35     n=strlen(S+1); ll now=1;
    36     if (P==2 || P==5) { solve(); return 0; }
    37     rep(i,1,m) scanf("%d%d",&a[i].l,&a[i].r),a[i].r++,a[i].id=i;
    38     for (int i=n; i; i--,now=now*10%P) s[i].x=(s[i+1].x+(S[i]-'0')*now)%P,s[i].y=i;
    39     s[++n].x=0; s[n].y=n; sort(s+1,s+n+1,cmp);
    40     rep(i,1,n){
    41         if (i==1 || s[i].x!=s[i-1].x) cnt++;
    42         c[s[i].y]=cnt;
    43     }
    44     int sz=(int)sqrt(n)+1;
    45     rep(i,1,n) bl[i]=(i-1)/sz;
    46     sort(a+1,a+m+1,cmp1);
    47     int L=1,R=1; num[c[1]]++;
    48     rep(i,1,m){
    49          while (R<a[i].r) work(++R,1);
    50          while (L>a[i].l) work(--L,1);
    51          while (R>a[i].r) work(R--,-1);
    52          while (L<a[i].l) work(L++,-1);
    53          res[a[i].id]=ans;
    54     }
    55     rep(i,1,m) printf("%lld
    ",res[i]);
    56     return 0;
    57 }
  • 相关阅读:
    [ 转载 ] Mysql 远程连接+开放80和3306端口 常用配置
    [ 转载 ] Mysql 数据库常用命令
    [ 转载 ] Centos 安装mysql后启动失败 出现 ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’
    [2020多校联考]手套
    [2020多校联考]糖果机器
    [2020多校联考]染色相邻的边
    [2020多校联考]四个质数的和
    [2020多校联考]简单题
    [2020多校联考]MC
    [2020多校联考]进化
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8283969.html
Copyright © 2020-2023  润新知