【bzoj4542】[Hnoi2016]大数 莫队
2016-04-20 19:54
363 查看
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
感觉可以离线?用a[i]表示前i个数连起来的数,则题目让求:
∑l∑r[s[r]−s[l−1]∗10r−l+1=0 (mod p)]
=∑l∑r[s[r]=s[l−1]∗10r−l+1 (mod p)]
=∑l∑r[s[r]∗(10r)−1=s[l−1]∗(10l−1)−1 (mod p)]
把s[i]∗(10i)−1离散化一下就是经典的莫队了。
然后关于p=2或5需要特判,因为这时候10i没有逆元,前缀和一下就行了。
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<map> #include<algorithm> using namespace std; typedef long long LL; const int SZ = 1000010; const int INF = 1000000010; int B,len,t[SZ],cnt = 0,n; map<LL,int> mp; LL s[SZ],p; char str[SZ]; struct haha{ int l,r,id; LL ans; }ask[SZ]; bool cmp1(haha a,haha b) { if(a.l / B == b.l / B) return a.r < b.r; return a.l < b.l; } bool cmp2(haha a,haha b) { return a.id < b.id; } int id[SZ]; LL get(LL x) { return x * (x - 1); } namespace work25{ int t[SZ],sum[SZ]; void solve() { for(int i = 1;i <= n;i ++) { if((str[i] - '0') % p == 0) t[i] = t[i - 1] + 1,sum[i] = sum[i - 1] + i; else t[i] = t[i - 1],sum[i] = sum[i - 1]; } int m; scanf("%d",&m); for(int i = 1;i <= m;i ++) { int l,r; scanf("%d%d",&l,&r); printf("%lld\n",(sum[r] - sum[l - 1]) - ((LL)t[r] - t[l - 1]) * (l - 1)); } } } int main() { scanf("%lld",&p); scanf("%s",str + 1); n = strlen(str + 1); if(p == 2 || p == 5) { work25 :: solve(); return 0; } B = sqrt(n); for(int i = n;i >= 1;i --) { static LL x = 1; x = x * 10 % p; s[i] = (s[i + 1] + x * (str[i] - '0') % p) % p; if(!mp[s[i]]) mp[s[i]] = ++ cnt; } for(int i = 1;i <= n + 1;i ++) id[i] = mp[s[i]]; int m; scanf("%d",&m); for(int i = 1;i <= m;i ++) { scanf("%d%d",&ask[i].l,&ask[i].r); ask[i].r ++; ask[i].id = i; } sort(ask + 1,ask + 1 + m,cmp1); LL ans = 0; for(int i = 1,l = 1,r = 0;i <= m;i ++) { for(;r > ask[i].r;r --) { ans -= get(t[id[r]]); t[id[r]] --; ans += get(t[id[r]]); } for(;r < ask[i].r;r ++) { ans -= get(t[id[r + 1]]); t[id[r + 1]] ++; ans += get(t[id[r + 1]]); } for(;l > ask[i].l;l --) { ans -= get(t[id[l - 1]]); t[id[l - 1]] ++; ans += get(t[id[l - 1]]); } for(;l < ask[i].l;l ++) { ans -= get(t[id[l]]); t[id[l]] --; ans += get(t[id[l]]); } ask[i].ans = ans >> 1; } sort(ask + 1,ask + 1 + m,cmp2); for(int i = 1;i <= m;i ++) printf("%lld\n",ask[i].ans); return 0; }
相关文章推荐
- java序列化(Serializable)的作用和反序列化
- Leetcode——binary-tree-maximum-path-sum
- 如何利用代码标注 MATLAB 图像上的某些点
- 操作系统开发系列—12.e.Makefile
- MapKit框架学习MKCircle 和MKCircleView
- 关于Java静态代码块、初始化块、构造函数的调用顺寻问题?
- Xcode在调试时查看到变量都是nil的问题
- 利用PHP的GD2图像函数 + mysql实现的一个简单的投票系统
- HDU-1020-Encoding,题意不清,其实很水~~
- 第八周
- zzuli 1877 蛤玮打扫教室
- 美团外卖app可行性分析
- 【Unity】6.8 Quaternion类(四元数)
- leecode Nim Game
- 数据总线和地址总线
- 在一个没有大神的公司如何成长
- 团队开发个人总结02
- 团队站立会议02
- JSP如何利用session在关闭浏览器时,自动清除缓存
- iOS——地图