来自学长的快乐AK题——Day8 荒地追猎
荒地追獵——數論
Description
數據規模
思路
設xi表示第i位的話就是
( ∑ i = 0 x i ? B i ) % ( B ? 1 ) = 0 (\sum_{i=0}x_i*B^i)\%(B-1)=0 (i=0∑?xi??Bi)%(B?1)=0
化簡一下得:
∑ i = 0 ( x i ? B i % ( B ? 1 ) ) = 0 \sum_{i=0}(x_i*B^i\%(B-1))=0 i=0∑?(xi??Bi%(B?1))=0
拆開單獨的一個來看:
x i ? B i % ( B ? 1 ) = ( x i % ( B ? 1 ) ) ? ( B i % ( B ? 1 ) ) = ( x i % ( B ? 1 ) ) ? 1 x_i*B^i\%(B-1)=(x_i\%(B-1))*(B^i\%(B-1))=(x_i\%(B-1))*1 xi??Bi%(B?1)=(xi?%(B?1))?(Bi%(B?1))=(xi?%(B?1))?1
求和后:
∑ i = 0 ( x i % ( B ? 1 ) ? 1 ) = ( ∑ i = 0 x i ) % ( B ? 1 ) = 0 \sum_{i=0}(x_i\%(B-1)*1)=(\sum_{i=0}x_i)\%(B-1)=0 i=0∑?(xi?%(B?1)?1)=(i=0∑?xi?)%(B?1)=0
所以其實就是各位數字的和為B-1的倍數就好了。
然后再回頭看題目發現有限制ai>=1。這樣如果用上所有數字的和對B-1取模為t的話,若t不為0,我們就讓at減去一個1就好了。
因為要讓結果最大,所以更大的數肯定放在更高的位上,更小的數肯定放在更低的位上。因此對于從小到大的數,其所放的位也是從低到高。
然后對于一個詢問,求a數組的前綴和然后二分。
代碼
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const ll N=1e6; ll b,q,a[N],s[N],sum; int main() {scanf("%lld%lld",&b,&q);for(ll i=0;i<b;i++)scanf("%lld",&a[i]),sum=(sum+a[i]*i)%(b-1);if(sum) a[sum]--;for(ll i=0;i<b;i++)s[i+1]=s[i]+a[i];for(ll i=1,x;i<=q;i++){scanf("%lld",&x);ll p=lower_bound(s+1,s+b+1,x+1)-s-1;if(p>=b) p=-1;printf("%lld\n",p);}return 0; }總結
以上是生活随笔為你收集整理的来自学长的快乐AK题——Day8 荒地追猎的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么时候可以用到强化学习?强化学习怎么用
- 下一篇: RTT之柿饼UI