题解:P5956 [POI 2017] Podzielno
P5956 [POI 2017] Podzielno 题解
tip
date: 2025/7/21DAY15
T1 也是花了 10 分钟场切,a_zjzj 还是太没水准了。
思路
对于任意大于 \(2\) 的正整数 \(n\),必有 \(n-1\) 与它互质。
形式化的:
\[\forall n \in (2,+\infty )\cap\N,\gcd(n,n-1)=1 . \]
那么对于任意 \(B\) 进制数 \(A\)。
\[\because B \equiv 1 \pmod{B-1}
\]
\[\therefore B^i \equiv 1 \pmod{B-1}
\]
\[\because A = \sum p_i\times B^i
\]
\[\therefore A \equiv \sum p_i \pmod{B-1}
\]
注意题目 \(1 \le a_i \le 10^6\),每一位数字至少有一个,那么只要删去一个 \(\sum a_i \times i\) 除以 \(B-1\) 的余数就能保证 \(X\) 是 \(B-1\) 的倍数。
注意:当 \(\sum a_i \times i\) 本身是 \(B-1\) 的倍数时,不必删去。
因此,我们只要删数后前缀和,二分 \(k\) 即可。
lower_bound 不会点这里。
不知道洛谷专栏什么时候修复,反正先放着。
希望早点修好吧。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int n,m,s;
int mod;
int a[N];
int pre[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
mod=n-1;
for(int i=0;i<n;i++)
cin>>a[i],s=(s+a[i]*i%mod)%mod;
if(s) a[s]--;//特判
pre[0]=a[0];
for(int i=1;i<n;i++)
pre[i]=pre[i-1]+a[i];
while(m--){
int k;
cin>>k;
int ans=lower_bound(pre,pre+n,k+1)-pre;
if(ans==n){
cout<<-1<<'\n';
continue;
}
cout<<ans<<'\n';
}
return 0;
}
完结撒花!!!

浙公网安备 33010602011771号