Question: Given a range, two operations, one is to assign the value of x to y, and the other is the sum value of the query range (x, y, here, the sum value is calculated as follows:
Example: H (f2,..., f5) = B ^ 0 * f5 + B ^ 1 * f4 + B ^ 2 * f3 + B ^ 3 * f2 (mod P)
This question is hidden ~~~ If we use a line segment tree, we use the va domain to store all the H (tr [x] in the tree. l, tr [x]. r). During the update, multiply the number of update points and the right endpoint of the interval (B ^ (tr [x]. r-pos), and multiply the right endpoint (B ^ (r-tr [x]. r )).
It should be noted that a negative number may be generated during the remainder process, and the result must be normalized.
# Include <iostream> # include <algorithm> # include <cmath> # include <functional> # include <cstdio> # include <cstdlib> # include <cstring> # include <string> # include <vector> # include <set> # include <queue> # include <stack> # include <climits> // # define MAX 100050 # define INF 0x7FFFFFFF # define L (x) x <1 # define R (x) x <1 | 1 using namespace std; int B, p, l, n; long B [MAX], ans; int a [MAX]; struct node {int l, r, mid; long va;} tr [MAX * 4]; void init () {memset (a, 0, sizeof (a); B [0] = 1; for (int I = 1; I <= l; I ++) {B [I] = (B [I-1] * B) % p ;}} void build (int l, int r, int x) {tr [x]. l = l; tr [x]. r = r; tr [x]. mid = (l + r)> 1; tr [x]. va = 0; if (l = r) return; build (l, tr [x]. mid, L (x); build (tr [x]. mid + 1, r, R (x);} void update (int l, int x, int va) {tr [x]. va = (tr [x]. va + B [tr [x]. r-l] * va % p) % p; if (tr [x]. va <0) tr [x]. va + = p; if (tr [x]. l = tr [x]. r) return; if (l> tr [x]. mid) update (l, R (x), va); else update (l, L (x), va);} void query (int l, int r, int x) {if (l <= tr [x]. l & r> = tr [x]. r) {ans = (ans + B [r-tr [x]. r] * tr [x]. va % p) % p; if (ans <0) ans + = p; return;} if (r> tr [x]. mid) query (l, r, R (x); if (l <= tr [x]. mid) query (l, r, L (x);} void test () {for (int I = 0; I <= 3 * l; I ++) {printf ("% d % lld \ n", tr [I]. l, tr [I]. r, tr [I]. va) ;}} int main () {while (scanf ("% d", & B, & p, & l, & n )) {if (B = 0 & p = 0 & l = 0 & n = 0) break; char op; int x, y; init (); build (1, l, 1); for (int I = 0; I <n; I ++) {getchar (); scanf ("% c % d ", & op, & x, & y); if (op = 'E') {update (x, 1, y-a [x]); a [x] = y;} else {ans = 0; // test (); query (x, y, 1); printf ("% lld \ n ", ans) ;}} puts ("-") ;}return 0 ;}