• [洛谷P4118][Ynoi2016]炸脖龙I([洛谷P3934]Nephren Ruq Insania)


    题目大意:有$n$个数,每个数为$s_i$,两个操作:

    1. $1;l;r;x:$表示将区间$[l,r]$内的数加上$x$
    2. $2;l;r;p:$表示求$s_l^{s_{l+1}^{^{s_{l+2}dots}}}mod p$直到$s_r$

    题解:区间加可以通过树状数组维护,考虑操作二,由扩展欧拉定理可得:
    $$
    a^bequiv
    egin{cases}
    a^{bmod{varphi(p)}} &(a,b)=1\
    a^b &(a,b) ot=1,b<varphi(p)\
    a^{bmod{varphi(p)}+varphi(p)} &(a,p) ot=1,bgeqslantvarphi(p)
    end{cases}
    pmod{p}
    $$
    $varphi$函数最多递归$O(log_2)$层就会变成$1$,可以暴力算

    注意要在快速幂里面记录取过模,若取过,最后要加上一个$p$

    卡点:没注意快速幂中部分,没有开$long;long$

    C++ Code:

    #include <cstdio>
    #include <cctype>
    namespace __IO {
    	namespace R {
    		int x, ch;
    		inline int read() {
    			while (isspace(ch = getchar()));
    			for (x = ch & 15; isdigit(ch = getchar()); ) x = x * 10 + (ch & 15);
    			return x;
    		}
    	}
    }
    using __IO::R::read;
    
    #define maxn 500010
    
    int n, m;
    namespace BIT {
    	long long Tr[maxn], res;
    	inline void add(int p, const int x) {for (; p <= n; p += p & -p) Tr[p] += x;}
    	inline long long ask(int p) {for (res = 0; p; p &= p - 1) res += Tr[p]; return res;}
    }
    
    namespace Math {
    	const int N = 2e7 + 1;
    	int phi[N], plist[N], ptot;
    	bool notp[N];
    	void sieve() {
    		phi[1] = 1;
    		for (int i = 2; i < N; i++) {
    			if (!notp[i]) phi[plist[ptot++] = i] = i - 1;
    			for (int j = 0, t; j < ptot && (t = i * plist[j]) < N; j++) {
    				notp[t] = true;
    				if (i % plist[j] == 0) {
    					phi[t] = phi[i] * plist[j];
    					break;
    				}
    				phi[t] = phi[i] * phi[plist[j]];
    			}
    		}
    	}
    
    	inline long long pw(long long base, long long p, const int mod) {
    		long long res = 1, b = base, tmp = 0;
    		if (b >= mod && p) tmp = mod, b %= mod;
    		for (; p; p >>= 1) {
    			if (p & 1) {
    				res = res * b;
    				if (res >= mod) tmp = mod, res %= mod;
    			}
    			b = b * b;
    			if (b >= mod && p >> 1) tmp = mod, b %= mod;
    		}
    		return res + tmp;
    	}
    }
    using Math::phi;
    
    long long query(const int l, const int r, const int p) {
    	const long long x = BIT::ask(l);
    	if (!x) return 0;
    	if (x % p == 0) return p;
    	if (l == r) return x >= p ? x % p + p : x;
    	return Math::pw(x, query(l + 1, r, phi[p]), p);
    }
    
    int main() {
    	Math::sieve();
    	n = read(), m = read();
    	for (int i = 1, last = 0, x; i <= n; ++i) {
    		x = read();
    		BIT::add(i, x - last);
    		last = x;
    	}
    	while (m --> 0) {
    		int op = read(), l = read(), r = read(), x = read();
    		if (op == 1) BIT::add(l, x), BIT::add(r + 1, -x);
    		else printf("%lld
    ", query(l, r, x) % x);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    attr 修改IMG src
    64转2
    :eq
    DOM0和D0M2级事件
    c's's透明度
    span标签 宽度无效解决方案
    CSS 点击事件
    input点击后的 默认边框去除
    js
    CSS 的 ID 和 Class 有什么区别,如何正确使用它们。
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10113135.html
Copyright © 2020-2023  润新知