2017.11.9 T1 2048
題目描述
Tom 最近在研究迴文數字。
假設 s[i] 是長度爲 i 的迴文數個數(不含前導0),則對於給定的正整數 n 有:
以上等式中最後面的括號是布爾表達式,Tom 想知道S[n] mod 233333 的值是多少。
輸入格式
第一行一個正整數 T 。
接下來輸出共 T 行,每行一個正整數 n 。
輸出格式
輸出共 T 行,每行一個整數,表示 S[n] mod 233333 。
樣例數據
輸入
1
2
輸出
9
備註
【數據規模與約定】
對於 30% 的數據:
對於另 20% 的數據:
對於另 20% 的數據:
對於 100% 的數據:
分析:表示看到n竟然有
然後就誤入歧途,開始瘋狂找取模後的規律(每次加的數都不一樣怎麼可能有規律……)。但找到的這種頭幾位是n-1中間夾(n-1)/2個7末尾9的規律對正解很有幫助,
(其實我更糾結於取了模還可以正常運算嗎,事實證明加、減、乘都是可以的)
然而真正的正解是用到了NOI知識的,因爲233333不是質數,要求逆元,由於我寫的是NOIP的總結,就不說了。
代碼
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<queue>
#include<set>
using namespace std;
int getint()
{
int sum=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-')
{
f=-1;
ch=getchar();
}
for(;isdigit(ch);ch=getchar())
sum=(sum<<3)+(sum<<1)+ch-48;
return sum*f;
}
const int mo=233333;
int T,n,len;
long long shi[40],sum[40],x,y;
void pre()
{
shi[0]=10;
for(int i=1;i<=30;++i)
shi[i]=(shi[i-1]*shi[i-1])%mo;//先得求有2^k個0的數
sum[0]=7;
for(int i=1;i<=30;++i)
sum[i]=(sum[i-1]+sum[i-1]*shi[i-1])%mo;//現在可以求有2^k個7的數了
}
int main()
{
freopen("bug.in","r",stdin);
freopen("bug.out","w",stdout);
pre();
T=getint();
while(T--)
{
n=getint();
if(n%2==0)//偶數判掉
n=n-1;
len=n/2;
x=9,y=10;//先把個位的9加上,y記錄7應該從第幾位開始放
for(int i=30;i>=0;--i)
if(len&(1<<i))//倍增找,滿足就加上
{
x=(x+sum[i]*y%mo)%mo;//新增2^i個7
y=(y*shi[i])%mo;//下次再加就要再往前放2^i位了
}
x=(x+(long long)(n-1)*y%mo)%mo;//加上最前面的n-1
cout<<x<<'\n';
}
return 0;
}
本題結。