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; } }

 

posted @ 2022-09-14 01:24  er007  阅读(26)  评论(0编辑  收藏  举报