【CodeForces468】C. Hack it!(構造)

傳送門


題解:

由於我校模擬考的時候 l,r,al,r,a 的限制爲 1e16,所以這裏講一種把 l,rl,r 往小了放的方法。

首先問題轉化爲找到兩個前綴使得答案 %a\%a 相等,根據抽屜原理問題一定有解。

容易注意到 f(x+y)=f(x)+f(y)f(x+y)=f(x)+f(y) 當且僅當 x+yx+y 沒有進位。

容易想到把其中一個後面若干位設置成 00,這樣可以任意放。

那麼考慮求出 i=010k1f(i)p(moda)\sum_{i=0}^{10^k-1}f(i)\equiv p\pmod a

對於 x<9×10k,f(x+10k)=f(x)+1x < 9\times10^k,f(x+10^k)=f(x)+1,於是不難發現,當 ap9eka-p\leq 9ek 的時候,i=ap10k+ap1f(i)0(moda)\sum_{i=a-p}^{10^k+a-p-1}f(i)\equiv 0\pmod a

該做法在 a9×10ka\leq 9\times 10^k 的時候必然出解。

當然還可以枚舉上標爲 t×10kt\times10^k,則 ap(10t)×10ka-p\leq (10-t)\times 10^k 的時候可以找到一組解,不過原題限制很寬鬆,你甚至可以直接考慮 k=18k=18


代碼:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

using std::cerr;
using std::cout;

ll a;

ll pw[20];

void Main(){
	std::cin>>a;
	for(int re i=pw[0]=1;i<=18;++i)
		pw[i]=pw[i-1]*10;
	for(int re k=1;k<=18;++k){
		ll p=pw[k-1]%a*k%a*45%a;
		ll l=a-p,r=pw[k]+a-p-1;
		if(l>=0&&l/9<=pw[k]){
			cout<<l<<" "<<r<<"\n";
			return ;
		}
	}cout<<"fuck\n";
}

inline void file(){
#ifdef zxyoi
	freopen("hack.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
	freopen("hack.in","r",stdin);
	freopen("hack.out","w",stdout);
#endif
#endif
}signed main(){file();Main();return 0;}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章