10297 : Podzielno 數論
阿新 • • 發佈:2018-12-09
結論: 一個數能被B-1整除當且僅當這個數在B進位制下的每一位的和能被B-1整除。
證明:
當一個數的某一位+1時,若進位,則這一位要減去B-1,下一位要+1,則總的貢獻是+1.
當一個數的某一位-1時,若退位,則這一位要加上B-1,下一位要-1,則總的貢獻是-1.
於是當一個數加上B-1時,它在B進位制下每一位的總和對B-1取模的值是不變的。
a*Bk≡a (mod (B-1) )
於是只要使所有位之和是(B-1)的倍數就可以了。
又a[i]>=1,只需刪去sum%(B-1)就可以了。
詢問用二分。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int N=1000005; int B,q; LL a[N]; LL read() { LL x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { B = read();q = read(); int s = 0; for (int i = 0; i < B; i++) {a[i]=read(); s=(s+(LL)i*a[i]%(B-1))%(B-1);} if (s) a[s]--; for (int i = 1; i < B; i++) a[i] += a[i-1]; while (q--) { LL x = read() + 1; int l = 0,r = B-1; while (l <= r) { int mid = (l + r) / 2; if (a[mid] >= x) r = mid - 1; else l = mid + 1; } if (r == B - 1) cout << "-1\n"; else printf("%d\n", r + 1); } return 0; }
先開始超時了,然後看了 https://blog.csdn.net/qq_33229466/article/details/75007075這位大佬的,用了read();
可能這就是傳說中的按位讀取吧。。。。
每次打完訓練賽就自閉,比每天刷USACO更抑鬱。失去夢想變成鹹魚。