题解:关注 small_lemon_qwq 谢谢喵
small_lemon_qwq · · 题解
打表,我和你拼了!
正解,我和你拼了!
众所周知,打表是一种非常优秀的算法,只是有以下缺点:
- 无法提交(本题可以用分段打表,没有这个问题);
- 被骂。
所以我们为了不被骂,只能另寻他法。
令
注意到,从
这样时间复杂度就是了
这个题解启发我们可以用高精度动态求检查是否存在为
考虑计算时间复杂度,
注意 C++11 和 C++14(GCC 9) 的区别。
#include<bits/stdc++.h>
using namespace std;
int d=1,x;
unsigned n,i=1,num[10]={1};
constexpr unsigned p[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
unsigned stk[10],tp;
void update(){
register int k=0;
++num[0];
tp+=(num[0]==7)-(num[0]==8);
if(__builtin_expect(num[0]==7,0))stk[tp]=0;
while(__builtin_expect(num[k]>9,0)){
num[k]-=10;
num[++k]++;
tp+=(num[k]==7)-(num[k]==8);
if(__builtin_expect(num[k]==7,0))stk[tp]=k;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
// if(n==899999999){
// cout<<959;
// return 0;
// }//看清楚,我注释了的
#ifndef ONLINE_JUDGE
auto start=clock();
#endif
while(__builtin_expect(i<=n,1)){
x+=d;
register int tmp=__builtin_expect(tp,0)?stk[tp]:(__builtin_expect(i%7==0,0)-1);
if(tmp!=-1)d=~d+1;
if(__builtin_expect(tmp>0,0)){
if(__builtin_expect(i+p[tmp]<=n,1)){
i+=p[tmp];
++num[tmp];
--tp;
}else{
if((n-i)&1)x+=d;
break;
}
x+=d;
d=~d+1;
continue;
}
++i,update();
}
cout<<(x%1337+1336)%1337+1;
#ifndef ONLINE_JUDGE
cout<<"\n"<<clock()-start;
#endif
return 0;
}
这个代码 C++14(GCC 9) 会 TLE,不知道为什么,很玄学。
这样在