time:2016.09.10
author:xiaoyimi
傳送門思路:
神奇的東西
斷斷續續地想了一天沒搞出來
因為沒想到離散化(╯‵□′)╯︵┻━┻
有乙個有趣的性質 定義t
i=∑n
j=is
[i]⋅
10n−j
+1 (
mod
p)s[i]是原字串中第i個位置的數字
也就是說123321
在不考慮p的情況下t4
=321
,t1=
123321
如果存在x,y(x<y) tx
=ty 且p!=2,p!=5 那麼s
[x..
y]就是乙個合法解 tx
−ty=
s[x.
.y]⋅
10n−y
p是非2非5的質數 那麼s
[x..
y]這個數一定包含質因子p
然後就可以直接莫隊,通過記錄區間內每一段字尾mod p的值就可以計算了
由於要加的是相同個數的數量,所以每個區間[l,r]要變成[l,r+1],字串最後添0
注意離散化,注意2,5的特判
**:
#include
#include
#include
#include
#define m 100003
#define ll long long
using namespace std;
int n,m;
int block[m],sum[m];
ll p,ans[m],a[m],b[m],cnt[m],t[m];
char s[m];
struct queryq[m];
int in()
bool cmp(query a,query b)
, printf("%lld\n",cnt[q[i].r]-cnt[q[i].l-1]-(t[q[i].r]-t[q[i].l-1])*(
q[i].l-1));
}main()
ll t=1;s[++n]='0';
for (int i=1;i<=m;++i) q[i]=(query);
for (int i=n;i>=1;--i)
a[i]=b[i]=(a[i+1]+t*(
s[i]-'0'))%p,
t=t*10
%p; sort(b+1,b+n+1);
b[0]=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b;
block[0]=sqrt(n);
for (int i=1;i<=n;++i) block[i]=(i+1)/block[0];
sort(q+1,q+m+1,cmp);
int l=1,r=0;ll s=0;
for (int i=1;i<=m;++i)
for (int i=1;i<=m;++i) printf("%lld\n",ans[i]);
}
bzoj4542 Hnoi2016 大數 莫隊
小 b 有乙個很大的數 s,長度達到了 n 位 這個數可以看成是乙個串,它可能有前導 0,例如00009312345 小b還有乙個素數p。現在,小 b 提出了 m 個詢問,每個詢問求 s 的乙個子串中有多少子串是 p 的倍數 0 也 是p 的倍數 例如 s為0077時,其子串 007有6個子串 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 的倍數,那麼...