小 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的倍數。
第一行乙個整數: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為素數
輸出m行,每行乙個整數,第 i行是第 i個詢問的答案。
11
121121
3 1 6
1 5
1 4
5
32
//第乙個詢問問的是整個串,滿足條件的子串分別有:121121,2112,11,121,121。
2016.4.19新加資料一組
感覺可以離線?
用a[i]表示前i個數連起來的數,則題目讓求:∑l
∑r[s
[r]−
s[l−
1]∗10
r−l+
1=0(
modp
)] =
∑l∑r
[s[r
]=s[
l−1]
∗10r−
l+1(
modp
)] =
∑l∑r
[s[r
]∗(10
r)−1
=s[l
−1]∗
(10l−
1)−1
(mod
p)]
把s[i
]∗(10
i)−1
離散化一下就是經典的莫隊了。
然後關於p=2或5需要特判,因為這時候10i
沒有逆元,字首和一下就行了。
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long ll;
const
int sz = 1000010;
const
int inf = 1000000010;
int b,len,t[sz],cnt = 0,n;
mapint> mp;
ll s[sz],p;
char str[sz];
struct hahaask[sz];
bool cmp1(haha a,haha b)
bool cmp2(haha a,haha b)
int id[sz];
ll get(ll x)
namespace work25
int m;
scanf("%d",&m);
for(int i = 1;i <= m;i ++)
}}int main()
b = sqrt(n);
for(int i = n;i >= 1;i --)
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 ++)
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 ++)
for(;l > ask[i].l;l --)
for(;l < ask[i].l;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;}
BZOJ4542 Hnoi2016 大數 莫隊
小 b 有乙個很大的數 s,長度達到了 n 位 這個數可以看成是乙個串,它可能有前導 0,例如00009312345。小b還有乙個素數p。現在,小 b 提出了 m 個詢問,每個詢問求 s 的乙個子串中有多少子串是 p 的倍數 0 也是p 的倍數 例如 s為0077時,其子串 007有6個子串 0,0...
4542 Hnoi2016 大數 莫隊演算法
555我好弱啊 都說今年的hnoi是無腦資料結構賽,都很好想只是碼 的問題,然而我還是不會做這道題。要退役了啊啊啊。首先我們令si 表示以i 為開頭的字尾形成的數字。對於p 2且p 5的時候,我們可以發現,若存在l,r 滿足sl sr 1 modp 則區間 l r 組成的數字一定是 p 的倍數,那麼...
BZOJ4542 大數, 莫隊
time 2016.09.10 author xiaoyimi 傳送門思路 神奇的東西 斷斷續續地想了一天沒搞出來 因為沒想到離散化 有乙個有趣的性質 定義t i n j is i 10n j 1 mod p s i 是原字串中第i個位置的數字 也就是說123321 在不考慮p的情況下t4 321 ...