题目分析:
表格这么大,显然需要一些奇妙的剪枝。
小学生告诉你 :
a
b
c
d
e
‾
+
e
d
c
b
a
‾
=
10001
(
a
+
e
)
+
1010
(
b
+
d
)
+
200
c
\overline{abcde}+\overline{edcba}=10001(a+e)+1010(b+d)+200c
abcde+edcba=10001(a+e)+1010(b+d)+200c
a
+
e
∈
(
0
,
18
]
,
b
+
d
∈
[
0
,
18
]
,
c
∈
[
0
,
9
]
a+e\in(0,18],b+d\in[0,18],c\in[0,9]
a+e∈(0,18],b+d∈[0,18],c∈[0,9]
可以发现,由五位数形成的形为
x
+
r
e
v
(
x
)
x+rev(x)
x+rev(x)的数最多只有
1
9
2
∗
10
19^2*10
192∗10个数。
所以考虑暴力把所有形为 x + r e v ( x ) x+rev(x) x+rev(x)的数全部搜出来,大概是 1 9 l e n / 2 ∗ l e n 19^{len/2}*len 19len/2∗len的复杂度。测试一波可以发现只有约250w个数,这就很愉快了。
把这250w个数记为S集合
记每个数在表格中的出现次数(除去第一列出现)为
f
[
i
]
f[i]
f[i],那么对于在S集合中的每一个
j
+
r
e
v
(
j
)
=
i
j+rev(j)=i
j+rev(j)=i就有
f
[
i
]
+
=
f
[
j
]
f[i]+=f[j]
f[i]+=f[j],最后
f
[
i
]
f[i]
f[i]还要加上由第一列的
j
j
j推出来的数量(其实就是dfs时的方案数)
对 f f f做一个前缀和,询问的时候lower_bound一下,再加上区间长度(第一列的数)就是答案。
Code:
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define LL long long
#define maxn 2666666
#define x first
#define y second
using namespace std;
char cb[1<<20],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<20,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &a){
char c;while(!isdigit(c=getc()));
for(a=c-'0';isdigit(c=getc());a=a*10+c-'0');
}
int Q,ans,n,m;
LL s[maxn],pw[12],t[maxn];
pair<LL,LL>a[maxn];
void dfs(int k,int len,LL x,LL w,bool fp){
if(x>pw[10]) return;
if(2*k+1>len) {a[++m]=make_pair(x,w);return;}
if(k==len-k-1) for(int i=fp?1:0;i<=9;i++) dfs(k+1,len,x+2*i*pw[k],w,0);
else{
if(!fp) dfs(k+1,len,x,w,0);
for(int i=1;i<=18;i++) dfs(k+1,len,x+i*(pw[k]+pw[len-k-1]),w*(i<=9?i+!fp:19-i),0);
}
}
inline LL rev(LL x){
LL y=0;while(x) y=y*10+x%10,x/=10;
return y;
}
int main()
{
freopen("1.in","r",stdin);
pw[0]=1;for(int i=1;i<=10;i++) pw[i]=pw[i-1]*10;
for(int len=1;len<=10;len++) dfs(0,len,0,1,1);
sort(a+1,a+1+m);
for(int i=2;i<=m+1;i++)
if(a[i].x==a[i-1].x) a[i].y+=a[i-1].y;
else t[++n]=a[i-1].x,s[n]=a[i-1].y;
for(int i=1;i<=n;i++)
s[lower_bound(t+1,t+n+1,t[i]+rev(t[i]))-t]+=s[i],
s[i]+=s[i-1];
read(Q);
LL L,R,P;
while(Q--){
read(L),read(R),read(P);
ans^=(s[upper_bound(t+1,t+n+1,R)-t-1]-s[lower_bound(t+1,t+n+1,L)-t-1]+R-L+1)%P;
}
printf("%d",ans);
}