zoukankan      html  css  js  c++  java
  • 【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 ight ]}$$


      即以位置$x$开头的后缀的数字$%P$之后的值为$val[x]$,如果一个数字对应区间${[l,r]}$它$%p$为$0$的充要条件为${val[l]=val[r-1]}$,然后套上莫队算法,离散化$val$数组,就变成了经典的查询一个区间相同数字的点对有多少个。

      注意:$p=2,5$的情况中并不满足以上性质,记一下前缀和然后特判即可。


      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<cstring>
      8 using namespace std;
      9 #define maxn 300100
     10 #define llg long long
     11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     12 llg n,m,p,quan[maxn],tail,val[maxn],len,se[maxn],KUAI;
     13 long long ans,Ans[maxn],jisuan1[maxn],jisuan2[maxn];
     14 char s[maxn];
     15 struct Q_
     16 {
     17     llg l,r,num;
     18 }ask[maxn];
     19 
     20 bool cmp(const Q_&a,const Q_&b) {if (a.l/KUAI==b.l/KUAI) return a.r<b.r; else return a.l/KUAI<b.l/KUAI; }
     21 
     22 llg find(llg x)
     23 {
     24     llg l=1,r=len,wz=-1,mid;
     25     while (l<=r)
     26     {
     27         mid=(l+r)>>1;
     28         if (quan[mid]<=x) {wz=mid; l=mid+1;}else {r=mid-1;} 
     29     }
     30     return wz;
     31 }
     32 
     33 void solve()
     34 {
     35     cin>>m;
     36     for(int i=1;i<=n;i++)
     37     { 
     38         jisuan1[i]=jisuan1[i-1]; jisuan2[i]=jisuan2[i-1];
     39         if( (s[i]-'0')%p==0 )
     40              {
     41             jisuan1[i]++;
     42             jisuan2[i]+=i;
     43              }
     44    
     45     }
     46     for(int i=1;i<=m;i++)
     47     {
     48         llg x,y;
     49         scanf("%lld%lld",&x,&y);
     50         printf("%lld
    ",jisuan2[y]-jisuan2[x-1] - (x-1)*(jisuan1[y]-jisuan1[x-1]));
     51     }
     52 }
     53 
     54 void init()
     55 {
     56     cin>>p;
     57     scanf("%s",s+1);
     58     n=strlen(s+1);
     59     KUAI=sqrt(n)+1;
     60     if (p==5 || p==2) return ;
     61     cin>>m;
     62     for (llg i=1;i<=m;i++) scanf("%lld%lld",&ask[i].l,&ask[i].r),ask[i].r++,ask[i].num=i;
     63     sort(ask+1,ask+m+1,cmp);
     64     llg C=1;
     65     tail=1;quan[1]=0; 
     66     for (llg i=n;i>=1;i--)
     67     {
     68         val[i]=val[i+1]+C*(s[i]-'0');
     69         val[i]%=p;
     70         quan[++tail]=val[i];
     71         C*=10; C%=p;
     72     }
     73     sort(quan+1,quan+tail+1);
     74     len=unique(quan+1,quan+tail+1)-(quan+1);
     75     for (llg i=1;i<=n+1;i++) val[i]=find(val[i]); 
     76 }
     77 
     78 int main()
     79 {
     80     yyj("number");
     81     init();
     82     if (p==2 || p==5) {solve(); return 0;}
     83 
     84     llg l=ask[1].l,r=ask[1].r;
     85     for (llg i=l;i<=r;i++)
     86     {
     87         ans+=se[val[i]];
     88         se[val[i]]++;
     89     }
     90     Ans[ask[1].num]=ans;
     91     for (llg k=2;k<=m;k++)
     92     {
     93         llg nl=ask[k].l,nr=ask[k].r;
     94         if (nr>r)
     95         {
     96             for (llg i=r+1;i<=nr;i++)
     97             {
     98                 ans+=se[val[i]];
     99                 se[val[i]]++;
    100             }
    101         }
    102         if (nr<r)
    103         {
    104             for (llg i=r;i>nr;i--)
    105             {
    106                 ans-=se[val[i]]-1;
    107                 se[val[i]]--;
    108             }
    109         }
    110         if (l<nl)
    111         {
    112             for (llg i=l;i<nl;i++)
    113             {
    114                 ans-=se[val[i]]-1;
    115                 se[val[i]]--;
    116             }
    117         }
    118         if (l>nl)
    119         {
    120             for (llg i=l-1;i>=nl;i--)
    121             {
    122                 ans+=se[val[i]];
    123                 se[val[i]]++;
    124             }
    125         }
    126         Ans[ask[k].num]=ans;
    127         l=nl,r=nr;
    128     }
    129     for (llg i=1;i<=m;i++) printf("%lld
    ",Ans[i]); 
    130     return 0;
    131 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    leetcode701. Insert into a Binary Search Tree
    leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes
    leetcode 110. Balanced Binary Tree
    leetcode 104. Maximum Depth of Binary Tree 111. Minimum Depth of Binary Tree
    二叉树
    leetcode 124. Binary Tree Maximum Path Sum 、543. Diameter of Binary Tree(直径)
    5. Longest Palindromic Substring
    128. Longest Consecutive Sequence
    Mac OS下Android Studio的Java not found问题,androidfound
    安卓 AsyncHttpClient
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6399252.html
Copyright © 2011-2022 走看看