日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu_5085_Counting problem(莫队分块思想)

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu_5085_Counting problem(莫队分块思想) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目連接:hdu_5085_Counting problem

題意:給你一個計算公式,然后給你一個區間,問這個區間內滿足條件的數有多少個

題解:由于這個公式比較特殊,具有可加性,我們考慮講一個數分為兩個部分,這樣就可以用莫隊的思想均攤時間復雜度,將9位數分為一個4位和一個5位,這里我感覺sqr為10000 速度比較快。然后如果b小于sqr,那么直接暴力就行,如果b大于sqr,那么我們要把a和b都分為頭部和尾部(注意是閉區間,a需要減1),如果a小于sqr,那么他的頭部就為0,然后計算0-a的尾部,并將相應的值插入Hash表,然后計算以a頭部開頭滿足條件的數,記為reta,同理,計算0-b的尾部,記為retb,如果b尾小于a尾,就要先計算b再計算a,然后將0到sqr-1的數對應的值也全部插入Hash表,然后從a的頭到b的頭,尋找對應的值,這里要用一下容斥定理,retb-reta就是從[a,b]之間滿條件的數的個數.


1 #include<cstdio> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 typedef long long LL; 4 5 const LL M=(1<<20)-1,N=1e5+7,sqr=1e4; 6 LL K,a,b,ahd,bhd,bt,at,reta,retb,T,S,dt[10][16]; 7 inline LL pow(LL x,LL k){ 8 LL an=1; 9 while(k){ 10 if(k&1)an*=x; 11 k>>=1,x*=x; 12 } 13 return an; 14 } 15 //------------Hash table------------------------ 16 struct E{LL key;LL cnt;E *nxt;}*g[M+1],pool[N],*cur=pool,*p;LL vis[M+1]; 17 void init_Hash(){T++,cur=pool;} 18 inline void ins(LL key){ 19 if(key>S)return; 20 LL u=key&M; 21 if(vis[u]<T)vis[u]=T,g[u]=NULL; 22 for(p=g[u];p;p=p->nxt)if(p->key==key){p->cnt++;return;} 23 p=cur++,p->key=key,p->cnt=1,p->nxt=g[u],g[u]=p; 24 } 25 26 inline LL ask(LL key){ 27 if(key<0)return 0; 28 LL u=key&M; 29 if(vis[u]<T)return 0; 30 for(p=g[u];p;p=p->nxt)if(p->key==key)return p->cnt; 31 return 0; 32 } 33 //---------------------------------------------- 34 inline LL cal(LL x){ 35 LL an=0; 36 while(x)an+=dt[x%10][K],x/=10; 37 return an; 38 } 39 void init(){F(i,0,9)F(j,1,15)dt[i][j]=pow(i,j);} 40 int main(){ 41 init(); 42 while(~scanf("%lld%lld%lld%lld",&a,&b,&K,&S)){ 43 init_Hash(); 44 ahd=(a-1)/sqr,bhd=b/sqr,at=(a-1)%sqr,bt=b%sqr; 45 if(at<bt){ 46 F(i,0,at)ins(cal(i)); 47 reta=ask(S-cal(ahd)); 48 F(i,at+1,bt)ins(cal(i)); 49 retb=ask(S-cal(bhd)); 50 F(i,bt+1,sqr-1)ins(cal(i)); 51 }else{ 52 F(i,0,bt)ins(cal(i)); 53 retb=ask(S-cal(bhd)); 54 F(i,bt+1,at)ins(cal(i)); 55 reta=ask(S-cal(ahd)); 56 F(i,at+1,sqr-1)ins(cal(i)); 57 } 58 F(i,ahd,bhd-1)retb+=ask(S-cal(i)); 59 printf("%lld\n",retb-reta); 60 } 61 return 0; 62 } View Code

?



?

轉載于:https://www.cnblogs.com/bin-gege/p/5696092.html

總結

以上是生活随笔為你收集整理的hdu_5085_Counting problem(莫队分块思想)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。