码迷,mamicode.com
首页 > 其他好文 > 详细

HNOI 2016 乱做

时间:2016-04-23 13:15:43      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

 

4542: [Hnoi2016]大数

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 488  Solved: 182
[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新加数据一组

 

Source

 

挺可做的一道题,因为P为素数,所以预处理后缀和,答案就是l到r中后缀和相同的数,然后就用莫队搞一搞就行了,(2和5要特判,它只和末位相关)

技术分享
  1 //start:   finish:
  2 #include<bits/stdc++.h>
  3 #define maxn 100005
  4 using namespace std;
  5 int P;
  6 int a[maxn];
  7 int b[maxn];
  8 long long c[maxn];
  9 int d[maxn];
 10 char s[maxn];
 11 int u[maxn];
 12 struct node
 13 {
 14     int x,y;
 15     int id;
 16     int kuai;
 17 }q[maxn];
 18 int m;
 19 int ge[maxn];
 20 bool cmp(node a,node b)
 21 {
 22     if(a.kuai!=b.kuai)return a.kuai<b.kuai;
 23     else return a.y<b.y;
 24 }
 25 long long res[maxn];
 26 int n;
 27 long long ans=0;
 28 void insert(int x)
 29 {
 30 //    cout<<x<<endl;
 31     ans+=ge[x];
 32     ge[x]++;
 33     //cout<<ans<<" "<<mp[x]<<endl;
 34 }
 35 void del(int x)
 36 {
 37     ge[x]--;
 38     ans-=ge[x];
 39 }
 40 void solve()
 41 {
 42     for(int i=1;i<=n;i++)
 43     {
 44         if((s[i]-0)%P==0)
 45         {
 46             c[i]=i;
 47             d[i]=1;
 48         }
 49     }
 50     for(int i=1;i<=n;i++)
 51     {
 52         c[i]=c[i-1]+c[i];
 53         d[i]=d[i-1]+d[i];
 54     }
 55     scanf("%d",&m);
 56     for(int i=1;i<=m;i++)
 57     {
 58         int l,r;
 59         scanf("%d%d",&l,&r);
 60         printf("%lld\n",c[r]-c[l-1]-1ll*(l-1)*(d[r]-d[l-1]));
 61     }
 62 }
 63 int main()
 64 {
 65     scanf("%d",&P);
 66     scanf("%s",s+1);
 67     n=strlen(s+1);
 68     if(P==2 || P==5)
 69     {
 70         solve();
 71         return 0;
 72     }
 73     scanf("%d",&m);
 74     for(int i=1;i<=m;i++)
 75     {
 76         scanf("%d%d",&q[i].x,&q[i].y);
 77         q[i].kuai=q[i].x/500;
 78         q[i].y++;
 79         q[i].id=i;
 80     }
 81     b[0]=1;
 82     for(int i=1;i<=n;i++)
 83     {
 84         b[i]=1ll*b[i-1]*10%P;
 85     }
 86     for(int i=n;i>=1;i--)
 87     {
 88         a[i]=(1ll*b[n-i]*(s[i]-0)%P+a[i+1])%P;
 89         u[i]=a[i];
 90     //    cout<<a[i]<<endl;
 91     }
 92     u[n+1]=0;
 93     sort(u+1,u+n+2);
 94     int cx=unique(u+1,u+n+2)-u-1;
 95     for(int i=1;i<=n+1;i++)
 96     {
 97         a[i]=lower_bound(u+1,u+cx+1,a[i])-u;
 98     }
 99     sort(q+1,q+m+1,cmp);
100     int l=1,r=0;
101     for(int i=1;i<=m;i++)
102     {
103     //    cout<<"fffff"<<endl;
104         //cout<<q[i].x<<" "<<q[i].y<<endl;
105         while(r<q[i].y)insert(a[++r]);
106         while(r>q[i].y)del(a[r--]);
107         while(l<q[i].x)del(a[l++]);
108         while(l>q[i].x)insert(a[--l]);
109         res[q[i].id]=ans;
110     }
111     for(int i=1;i<=m;i++)
112     printf("%lld\n",res[i]);
113     return 0;
114 }
115 /*
116 11 
117 121121 
118 3 
119 1 6 
120 1 5 
121 1 4 
122 */
View Code

 

HNOI 2016 乱做

标签:

原文地址:http://www.cnblogs.com/sillygirl/p/5424285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!