[构造] Codeforces 468C #268 (Div. 1) C. Hack it!

来源:互联网 发布:北京青年旅舍.知乎 编辑:程序博客网 时间:2024/06/05 06:45

记f(x)为x的数位和。
求l,r使得sum (i=l..r) f(i) mod P=0
P<=10^18, 要求l,r<=10^200

由于有两个参数l,r,自由度太大,所以我们加一个限制使得r=l+10^19-1。
这个时候我们注意到将[l,r]变成[l+1,r+1],整体上加上了f(r+1)减去了f(l)。
而r+1和l只差一位,也就是f(r+1)-f(l)=1。
所以只要算出初值f(1)+…+f(10^19),然后看和P差多少,往右移这么多个即可。

#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>using namespace std;typedef unsigned long long ull;ull P;ull f[25],g[25];inline ull mul(ull a,int b){  ull ret=0;  for (;b;b>>=1,a=(a+a)%P)    if (b&1)      ret=(ret+a)%P;  return ret;}ull magic;int main(){  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  cin>>P;  f[0]=0; g[0]=1;  for (int i=1;i<=19;i++){    f[i]=(mul(f[i-1],10)+mul(g[i-1],45))%P;    g[i]=mul(g[i-1],10);  }  magic=(f[19]+1)%P;  ull x=(P-magic)%P;  cout<<1+x<<' '<<((ull)1e19)+x<<endl;  return 0;}
0 0
原创粉丝点击