[Six Provinces Entrance Examination 2017] Meeting is a greeting (extended Euler ’s theorem + preprocessing power)

https://www.luogu.com.cn/problem/P3747

I ca n’t remember the last time I encountered the extended Euler theorem.

\(a^b~mod~p=\)
\(b<\phi(p),a^b~mod~p\)
\(b\ge \phi(p),a^{b~mod~\phi(p)+\phi(p)}~mod~p\)

Suppose the sequence of modulus is always taken as \ (\ phi \) is \ (p [1], p [2],…, p [p0] (p0 \ le 2log_2 (mo)) \)

For this problem, you can record a \ (cnt \) for each number to indicate how many times it has been powed. After \ (cnt> p0 \) , it is the same as the value of \ (cnt = p0 + 1 \)

Note that it is the same value as \ (cnt = p0 + 1 \) . For convenience, open one more bit:p[++p0]=1

Use the line segment tree to maintain the minimum value of the interval \ (cnt \) , if \ (\ le p0 \) , just go ahead and modify it.

Each number needs to be modified \ (log \) times, and each modification requires \ (log ^ 2 \) time to find a new answer (a log comes from a fast power), so that T will be two points.

Note that the numbers are all \ (c \) , so preprocessing \ (c ^ {0..15000} \) and \ (c ^ {0..15000 * 15000} \) in \ (mod \) each \ (p [i] \) under the value, you can \ (O (2) \) fast power.

Code:

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int N = 50005;

int n, m, sp, c;
int v[N];

int phi(int n) {
	if(n == 1) return 1;
	int s = n;
	for(int x = 2; x * x <= n; x ++) if(n % x == 0) {
		s = s / x * (x - 1);
		for(; n % x == 0; n /= x);
	}
	if(n > 1) s = s / n * (n - 1);
	return s;
}

int p[N], p0;

namespace sub1 {
	struct P {
		ll x; int y;
		P(ll _x = 0, int _y = 0) {
			x = _x, y = _y;
		}
	};
	P mul(P a, P b, int mo) {
		a.y |= b.y;
		a.x *= b.x;
		if(a.x >= mo) a.x %= mo, a.y = 1;
		return a;
	}
	
	const int M = 15000;
	
	P t1[100][M], t2[100][M];
	
	void build() {
		fo(i, 1, p0) {
			t1[i][0] = t2[i][0] = P(1 % p[1], 1 >= p[1]);
			P w = P(c % p[i], c >= p[i]);
			fo(j, 1, M) t1[i][j] = mul(t1[i][j - 1], w, p[i]);
			w = t1[i][M];
			fo(j, 1, M) t2[i][j] = mul(t2[i][j - 1], w, p[i]);
		}
	}
	
	P b[N];
	ll calc(int *a, int a0) {
		a0 = min(a0, p0);
		b[a0] = P(a[a0] % p[a0], a[a0] >= p[a0]);
		fd(i, a0 - 1, 1) {
			int y = b[i + 1].x + (b[i + 1].y ? p[i + 1] : 0);
			int z1 = y % M, z2 = y / M;
			b[i] = mul(t1[i][z1], t2[i][z2], p[i]);
		}
		return b[1].x;
	}
}

using sub1 :: calc;

int a[N]; int a0;

#define i0 i + i
#define i1 i + i + 1
ll t[N * 4]; int mi[N * 4];

void bt(int i, int x, int y) {
	if(x == y) {
		t[i] = v[x] % p[1];
		return;
	}
	int m = x + y >> 1;
	bt(i0, x, m); bt(i1, m + 1, y);
	t[i] = (t[i0] + t[i1]) % p[1];
}
int pl, pr, px;
void add(int i, int x, int y) {
	if(mi[i] >= p0 - 1 || y < pl || x > pr) return;
	if(x == y) {
		mi[i] ++;
		a0 = mi[i] + 1;
		fo(j, 1, a0 - 1) a[j] = c; a[a0] = v[x];
		t[i] = calc(a, a0);
		return;
	}
	int m = x + y >> 1;
	add(i0, x, m); add(i1, m + 1, y);
	t[i] = (t[i0] + t[i1]) % p[1];
	mi[i] = min(mi[i0], mi[i1]);
}
void ft(int i, int x, int y) {
	if(y < pl || x > pr) return;
	if(x >= pl && y <= pr) {
		px = (px + t[i]) % p[1];
		return;
	}
	int m = x + y >> 1;
	ft(i0, x, m); ft(i1, m + 1, y);
}

int op;

int main() {
	scanf("%d %d %d %d", &n, &m, &sp, &c);
	p[p0 = 1] = sp;
	while(p[p0] != 1) p0 ++, p[p0] = phi(p[p0 - 1]);
	p[++ p0] = 1;
	fo(i, 1, n) scanf("%d", &v[i]);
	sub1 :: build();
	bt(1, 1, n);
	fo(ii, 1, m) {
		scanf("%d %d %d", &op, &pl, &pr);
		if(op == 0) {
			add(1, 1, n);
		} else {
			px = 0;
			ft(1, 1, n);
			pp("%d\n", px);
		}
	}
}

Guess you like

Origin www.cnblogs.com/coldchair/p/12716074.html