BZOJ4542 大數, 莫隊

2021-07-22 14:45:01 字數 1625 閱讀 1369

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 的倍數,那麼...