Challenge: Randomness
Subdomeniu: Probability (probability)
Scor cont: 120.0 / 120
Submission status: Accepted
Submission score: 1.0
Submission ID: 464736458
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/randomness/problem
Cerinta
You're given a string $S$ of $N$ characters. It's known that the string consists of lowercase Latin letters. The string is generated randomly. That means that every symbol is chosen randomly and independently from others from the set {'a', 'b', ..., 'z'}. All the letters have equal probability to appear.
You're given $Q$ queries on this string. Each query is of the form `P C`, where $P$ is an integer between $1$ and $N$ (both inclusive) and $C$ is a character from the set {'a', 'b', ..., 'z'}. Both $P$ and $C$ were chosen at random and independently from other queries.
When you have a query of the form `P C` you have to change the $P$<sup>$th$</sup> symbol of $S$ to $C$. After every change we ask you to output the number of distinct nonempty sub-strings of $S$.
Input Format
The first line of input consists of two single space-separated integers $N$ and $Q$, the length of the string $S$ and the number of queries, respectively.
The second line contains string $S$.
The following $Q$ lines describe the queries in the form `P C`, where $P$ and $C$ are also separated with a single space.
**Constraints**
$4 \le N \le 75000$
$4 \le Q \le 75000$
Output Format
Output $Q$ lines. Output the number of distinct substrings of $S$ after the $i$<sup>$th$</sup> query on the $i$<sup>$th$</sup> line of the output.
Cod sursa
//randomness.cpp
//Randomness
//Daily Challenges - Week 1
//Author: derekhh
#include<cstdio>
#include<cstring>
using namespace std;
char s[75001];
const int MOD = 1000003;
const int BASE = 27;
struct Node {
long long str;
int cnt;
Node* next;
};
Node* hash[MOD];
long long ans;
int n;
long long pow[10];
void modify(long long val, int delta)
{
int mod = val % MOD;
Node* cur = hash[mod];
Node* tmp = NULL;
bool newStr = true;
while (cur != NULL)
{
if (cur->str == val)
{
cur->cnt += delta;
if (cur->cnt == 0)
{
ans--;
if (tmp == NULL)
hash[mod] = hash[mod]->next;
else
tmp->next = cur->next;
}
return;
}
tmp = cur;
cur = cur->next;
}
Node* node = new Node;
node->str = val;
node->cnt = delta;
ans += delta;
node->next = hash[mod];
hash[mod] = node;
}
void init()
{
for (int i = 0; i < MOD; i++)
hash[i] = NULL;
for (int i = 0; i < n; i++)
{
long long val = 0;
for (int len = 1; len <= 9; len++)
{
if (i + len - 1 >= n) break;
val = val * BASE + s[i + len - 1] - 'a' + 1;
modify(val, 1);
}
}
}
void update(int p, char ch)
{
for (int i = p - 8; i <= p; i++)
{
long long val = 0;
for (int len = 1; len <= 9; len++)
{
if (i + len - 1 < 0 || i + len - 1 >= n) break;
val = val * BASE + s[i + len - 1] - 'a' + 1;
if (i + len - 1 >= p)
modify(val, -1);
}
}
s[p] = ch;
for (int i = p - 8; i <= p; i++)
{
long long val = 0;
for (int len = 1; len <= 9; len++)
{
if (i + len - 1 < 0 || i + len - 1 >= n) break;
val = val * BASE + s[i + len - 1] - 'a' + 1;
if (i + len - 1 >= p)
modify(val, 1);
}
}
}
int main()
{
int q;
scanf("%d %d", &n, &q); getchar();
scanf("%s", s);
init();
for (int i = 10; i <= n; i++)
ans += n - i + 1;
while (q--)
{
int p; char ch;
scanf("%d %c", &p, &ch); getchar();
update(p - 1, ch);
printf("%lld\n", ans);
}
return 0;
}
HackerRank Probability – Randomness
