一道典型的莫隊。
先預處理出字尾,即f[i]表示i~(n-1) mod p 的值.
但p的值不小,顯然不能直接存,加乙個離散化。
觀察題目,發現一串數s(l~r)整除p滿足s(l~n-1)%p==s(r+1~n-1)%p
但p值為2或5不滿足這個性質需要特判(不過資料中好像沒有,於是筆者沒寫,有興趣的可以自己去寫寫。。。。。。)
然後問題轉化為求一段區間中有幾對相等的f值。
套乙個莫隊。(ans(l,r)可以由【ans(l+1,r),ans(l-1,r),ans(l,r+1),ans(l,r-1)】推出,為保證時間複雜度,用個分塊【因為不會曼哈頓樹】)。
注意:要在數列的後面加乙個f值為0。
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=200000+10;
char a[maxn];
ll p,n,m,s[maxn],_10[maxn]/*_10[i]表示10的i次方modp*/,f[maxn]/*f[i]表示i~l mod p 的值*/,cd[maxn];
ll cur,sum[maxn],kuai,ans[maxn];
struct query
q[maxn];
//把每個區間(l,r)看成乙個點(x,y),相同塊中的點按y排序,否則按x排序,可以保證n^1.5的時間複雜度
bool operator < (const query& a,const query& b)
int main()
char c;
scanf("%s",a);
n=strlen(a);
kuai=(ll)sqrt((double)n);//按x座標分塊,kuai表示沒段塊的長度
cin>>m;
for(int i=1;i<=m;i++)
scanf("%lld
%lld",&q[i].x,&q[i].y),q[i].x--,q[i].t=i;
sort(q+1,q+m+1);
for(int i=0;is[i]=a[i]-'0';
f[n-1]=s[n-1]%p;
cd[n-1]=f[n-1];
for(int i=n-2;i>=0;i--)
//for(int i=0;iprintf("%lld ",f[i]);printf("\n");
//離散化
cd[n]=0;
sort(cd,cd+n+1);
int tot=0;
for(int i=1;i<=n;i++)
for(int i=0;iint mid,l=0,r=tot;
while(l>1;
if(cd[mid]1;
else r=mid;
}f[i]=l;
}//**
****
****
****
****
****
****
****
****
****
****
*****
int l,r;
l=1;r=0;
for(int i=1;i<=m;i++)
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return
0; }
/*樣例:
1112112131
6151
4*/
題解 HNOI 2016序列
collapse bzoj 這道題在hnoi2016中還算是好的了 這題中如若去掉多組詢問的話可以在o nlogn o n log n 的時間內得解 並查集 但多組詢問必定要優化,發現這種其他結構基本上無法涉足的題目就只能上莫隊了 我也不知道為啥想到莫隊,可能這就是題感吧 減去o nn o n n ...
bzoj4542 Hnoi2016 大數 莫隊
小 b 有乙個很大的數 s,長度達到了 n 位 這個數可以看成是乙個串,它可能有前導 0,例如00009312345 小b還有乙個素數p。現在,小 b 提出了 m 個詢問,每個詢問求 s 的乙個子串中有多少子串是 p 的倍數 0 也 是p 的倍數 例如 s為0077時,其子串 007有6個子串 0,...
4542 Hnoi2016 大數 莫隊演算法
555我好弱啊 都說今年的hnoi是無腦資料結構賽,都很好想只是碼 的問題,然而我還是不會做這道題。要退役了啊啊啊。首先我們令si 表示以i 為開頭的字尾形成的數字。對於p 2且p 5的時候,我們可以發現,若存在l,r 滿足sl sr 1 modp 則區間 l r 組成的數字一定是 p 的倍數,那麼...