Codeforces Round #820 (Div. 3) F 数字根-字符串哈希
https://codeforces.ml/contest/1729/problem/F
分析:
这题和数字根有关,数字根相当于base是10的字符串哈希(把整个处理出来,把前面*权值后删掉),只不过这个哈希值就是这一段值的大小,就可以用这个哈希值预处理出(l,r)范围内的数字根的大小
%9 满足分配率,所有左边的未知数 x 和右边的未知数 y 的大小是[0,8] ,将所有以 L 为起点,长度为 w 的数字根 % 9 之后的值 k ,将当前的 a 装入 v[a] ,然后遍历所有的值,寻找满足条件的情况就可以了
当遇到满足条件的情况,如果它们 % k 的值a 相同 ,v[a]里面装的左端点数量要大于等于2才行,因为如果只有一个,就不满足 L1 != L2 。然后取 L1 和 L2字典序最小的答案就可以了。
ps:注意p[0] = 1;
//#define int ll const int N = 2e5+10; int n,m,w; char s[N]; int p[N],val[N]; string str; //处理 l 到 r 区间内的数字根的值 int calc(int l,int r) { return ((s[r] - s[l-1] * p[r-l]) % 9 + 9) % 9; } void solve() { // cin>>n>>m; cin>>str; n = str.size(); str = ' ' + str; cin>>w>>m;
p[0] = 1; fo(i,1,n) { p[i] = p[i-1] * 10 % 9; s[i] = (s[i-1] * 10 + str[i] - '0') % 9; } vector<int> v[10]; for(int l = 1,r = l + w - 1;r <= n;l ++ ,r ++ ) { //计算所有以 l 为起点长度是 w 的字符串的数字根 % 9 之后的值 val[l] = ((s[r] - s[l-1] * p[r-l]) % 9 + 9) % 9; //将它的左坐标存到数组里 v[val[l]].pb(l); } while(m -- ) { pii res = {inf,inf}; int l,r,k;cin>>l>>r>>k; int t = calc(l,r); for(int i = 0;i <= 9;i ++ ) { if(v[i].empty()) continue; for(int j = 0;j <= 9;j ++ ) { if(v[j].empty()) continue; if((t * i + j) % 9 == k) { if(i == j && v[i].size() > 1) res = min(res,{v[i][0],v[i][1]}); if(i != j) res = min(res, {v[i][0],v[j][0]}); } } } if(res.first == inf) res = {-1,-1}; cout<<res.first<<' '<<res.second<<endl; } }