好朋友
题目描述
BLUESKY007有很多关系很好的朋友,他们无一例外,名字均由数字组成(首字符不为0)且含有"007"(例如“10007”,“10707”就是她的好朋友,而“97037”,“70709”不是),即对于字符串s存在i,j,k(i< j< k)满足\overline{s_is_js_k}=\overline{007}sisjsk=007.
虽然BLUESKY007眼力极佳,一眼就能看出一个人是不是自己的好朋友,但BLUESKY007是个蒟蒻,她并不擅长数数,但她又想知道在[li,ri]内有多少人是自己的好朋友,所以就找到了你来帮忙.
她会向你询问t次,由于询问次数可能很多,所以你只需要告诉她t次询问答案的异或和即可.
虽然BLUESKY007眼力极佳,一眼就能看出一个人是不是自己的好朋友,但BLUESKY007是个蒟蒻,她并不擅长数数,但她又想知道在[li,ri]内有多少人是自己的好朋友,所以就找到了你来帮忙.
她会向你询问t次,由于询问次数可能很多,所以你只需要告诉她t次询问答案的异或和即可.
输入描述:
第一行一个整数t,表示询问个数
接下来t行,每行两个整数li,ri
输出描述:
一行一个整数表示答案
输入
3 1 1000 233 666 999 999
输出
0
说明
在0~1000范围内不存在与题目要求相符的含有“007”的数,所以三次询问的答案都是0
输入
3 10000 10086 2333 23333 6666 66666
输出
132
备注:
对于20%的数据,li≤ri≤103
对于40%的数据,t≤50,li≤ri≤5·104
对于100%的数据,1≤t≤105,0≤li≤ri≤1018
#include<bits/stdc++.h> using namespace std; const int N = 20; typedef long long LL; LL dp[N][N][2][2], dim[N]; LL dfs(int pos, int zeros, bool ok, int f, int lim) { if (pos < 0) return f; if (!lim && ~dp[pos][zeros][ok][f]) return dp[pos][zeros][ok][f]; int up = lim ? dim[pos] : 9; LL ret = 0; for (int i = 0; i <= up; i++) { ret += dfs(pos - 1, ok ? zeros + (i == 0) : 0, ok || i != 0, f || (zeros >= 2 && i == 7), lim && i == up); } if (!lim) dp[pos][zeros][ok][f] = ret; return ret; } LL solve(LL x) { int len = 0; memset(dp, -1, sizeof(dp)); memset(dim, 0, sizeof(dim)); while (x) { dim[len++] = x % 10; x /= 10; } return dfs(len - 1, 0, false, 0, 1); } LL ask() { LL l, r; scanf("%lld%lld", &l, &r); return solve(r) - solve(max(l - 1, 0LL)); } int main() { int T; LL ret = 0; scanf("%d", &T); while (T--) ret ^= ask(); printf("%lld\n", ret); return 0; }

浙公网安备 33010602011771号