Codeforces Round 830

CF1732

A

降智打击。一个做法是预处理状压去除劣状态,然而傻逼做法是挨个判断 \(n,n-1\) 是否能使之变成1.

B

从第一个 1 开始将后面全部变成1即可。

C1/C2

仍然好做。考虑当答案集加入一个数 \(a_i\) 时,\(sum \leftarrow sum+a_i\)\(xor\leftarrow xor ⊕ a_i\)。显然前者比后者增多的只多不少。于是不难发现整个询问区间是一个答案,但是他要求长度最短。

这时发现左端点或右端点最多移动 \(\log_2 V\) 位置,因为固定一个端点,另一个端点要想使得答案不降只能把目前异或和为 \(0\) 的位变成 \(1\)

于是暴力枚举即可。当然,千万别忘了把序列中 \(0\) 删了考虑。

复杂度 \(O(q \log^2 V)\)

D1/D2

乱搞题,敢写就能过。

D1直接暴力用 map 维护出每一种查询的数目前跳到的答案然后暴力跳即可。复杂度易证。

D2考虑对于每一个询问的数 \(x\) 维护 set 表示 \(x\) 不大于目前跳到的答案的删除集合即可。再维护一个 set \(modify_x\) 表示跳到过 \(x\) 的查询数的集合即可。

E

感觉像省选题。略微卡常。知识点是分块,狄利克雷后缀和,\(O(1)\) gcd。

分块。对于散块暴力重构/查询,对于整块维护标记。

唯一的问题是预处理每个块中所有数和 \(x\) 的最小答案。其中 \(x\) 是值域中所有正整数。

发现可以枚举 \(gcd\),将块中最小有 \(gcd\) 作为因数的数用来更新所有有 \(gcd\) 作为因数的 \(x\)。这个可以只更新 \(x=gcd\) 这个位置,然后做狄利克雷后缀和即可。

还要预处理 \(O(1)\) gcd。

最后设块个数是 \(B\),复杂度 \(O(n B \ln \ln n+qB+\frac{qn}{B})\)

因为 \(n,q\) 同阶,块大设成 \(\sqrt{\frac{n}{\ln\ln n}}\) 可以做到 \(O(n\sqrt{n\ln\ln n})\)

比较难写,而且常数比较大,我全开了 long long 需要卡一下常才能过。

code:

#include<bits/stdc++.h>
namespace infinities{
    #define fint register int
    #define ls(i) (i << 1)
    #define rs(i) ((i << 1) | 1)
    #define pii pair<int, int>
    #define im int mid = (l + r) >> 1
    #define INT __int128
    #define int long long
    #define ui unsigned int
    #define lc ch[now][0]
    #define rc ch[now][1]
    const int INF = 1e18, maxn = 5e4 + 19, lim = 601;
    namespace FastIO{//10M
        const int S = 1e7; char num_[50]; int cnt_;
        inline int xchar(){static char buf[S]; static int len = 0, pos = 0; if(pos == len)pos = 0, len = fread(buf, 1, S, stdin); if(pos == len)exit(0); return buf[pos++];}
        inline int read(){fint x = 0, f = 1, ch = getchar(); while(ch < '0' || ch > '9'){if(ch == '-')f = -1; ch = getchar();}while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();} return x * f;}
        inline void write(int x){if(x == 0){putchar('0'); return;}if(x < 0)putchar('-'), x = -x; while(x)num_[++cnt_] = x % 10 ^ 48,x /= 10; while(cnt_)putchar(num_[cnt_--]);}
        inline void write(int x, char c){write(x), putchar(c);}
    }
    using namespace std;
    using namespace FastIO;
    namespace mystd{
        const int mod = 1e9 + 7;
        inline int qmin(int a, int b){return (a > b) ? b : a;} inline int qmax(int a, int b){return (a > b) ? a : b;}
        inline void chkmin(int &a, int b){a = min(a, b); return;} inline void chkmax(int &a, int b){a = max(a, b); return;}
        inline int qk_(int a, int b){return ((a + b) % mod + mod) % mod;} inline int qk(int a, int b){return (a + b < 0) ? a + b + mod : ((a + b >= mod) ? a + b - mod : a + b);}
        inline int mul(int a, int b){return (1ll * a * b % mod + mod) % mod;}
        inline int qpow(int x, int k){fint res = 1; for(; k; k = (k >> 1), x = 1ll * x * x % mod)if(k & 1)res = 1ll * res * x % mod; return res;}
        inline void looked(int a[], int n){for(fint i = 1; i < n; i++)write(a[i], ' '); write(a[n], '\n');} inline void debug(){puts("qwq");} inline void YES(){puts("YES");} inline void Yes(){puts("Yes");} inline void yes(){puts("yes");} inline void NO(){puts("NO");} inline void No(){puts("No");} inline void no(){puts("no");}
    }
    //using namespace mystd;
    void file(){freopen("a.in", "r", stdin), freopen("a.out", "w", stdout);}
    int n, q, size, a[maxn], ans[501][maxn], M = 50001, belong[maxn], L[maxn], R[maxn], N = 500, cnt[maxn], tag[maxn];
    int b[maxn]; int did[501][maxn];
    int nowans[501];
	vector<int>vec[maxn]; 
	vector<int>pr[maxn];
	int a1, a2, a3;
	int Gcd[lim + 1][lim + 1], cntt, pri[maxn], ispri[maxn], minp[maxn], st[maxn], top, can[maxn], now;
	int x[maxn][3];
	void work2(int nm){
		#define cnt cntt
		x[1][0] = x[1][1] = x[1][2] = 1;
		for(fint i = 2; i <= nm; i++){
			if(!ispri[i]){pri[++cnt] = i, x[i][0] = 1, x[i][1] = 1, x[i][2] = i, minp[i] = i, pr[i].push_back(i);}
			else x[i][0] = x[i / minp[i]][0] * minp[i], x[i][1] = x[i / minp[i]][1], x[i][2] = x[i / minp[i]][2];
			if(x[i][0] > x[i][1])swap(x[i][0], x[i][1]);
			if(x[i][1] > x[i][2])swap(x[i][1], x[i][2]);
			for(fint j = 1; j <= cnt && i * pri[j] <= nm; j++){
				if(!ispri[i * pri[j]]){ispri[i * pri[j]] = 1, minp[i * pri[j]] = pri[j], pr[i * pri[j]] = pr[i]; if(i % pri[j])pr[i * pri[j]].push_back(pri[j]);}
				if(i % pri[j] == 0)break;
			}
		}
		#undef cnt
	}
	int gcd(int u, int v){
		if(u <= lim)return Gcd[u][v % u]; if(v <= lim)return Gcd[u % v][v];
		fint a = 0, tmp = 1, res = 1;
		for(fint i = 0; i < 3; i++){
			a = x[u][i];
			if(a > lim){if(v % a == 0)tmp = a;else tmp = 1;}else tmp = Gcd[a][v % a];
			res *= tmp, v /= tmp;
		}
		return res;
	}
	int sol(int i){a1 = b[i], a2 = tag[belong[i]] ? tag[belong[i]] : a[i], a3 = gcd(a1, a2); return a1/a3*a2/a3;}
	void work(int l){
		fint ql = belong[l];
		nowans[ql] = INF;
		for(fint i = L[l]; i <= R[l]; i++){nowans[ql] = min(nowans[ql], sol(i));}
	}
	#define __gcd gcd
	void dfs(int res, int i, int mx){
		if(i > top)return;
		if(res * st[i] > mx)return;
		for(fint j = st[i]; j * res <= mx; j *= st[i]){can[++now] = j * res; dfs(j * res, i + 1, mx);}
		dfs(res, i + 1, mx);
	}
	bool ck(int j){
		for(fint i = j + 1; i <= R[j]; i++)if(b[i] == b[j])return 0;
		return 1;
	}
    signed main(){
    	n = read(), q = read(), N = min(N, n), size = (n + N - 1) / N;
		for(fint i = 0; i <= lim; i++)Gcd[i][0] = Gcd[0][i] = i;
		for(fint i = 1; i <= lim; i++)for(fint j = 1; j <= i; j++)Gcd[i][j] = Gcd[j][i] = Gcd[i % j][j];
		work2(50006);
    	for(fint i = 1; i <= N; i++)for(fint j = 1; j <= M; j++)ans[i][j] = INF;
		for(fint i = 1; i <= n; i++)a[i] = read();
		for(fint i = 1; i <= n; i++)b[i] = read();
    	for(fint i = 1; i <= N; i++){
    		nowans[i] = INF;
			for(fint j = (i - 1) * size + 1; j <= min(n, i * size); j++){
				fint gd = __gcd(a[j], b[j]);
				belong[j] = i, nowans[i] = min(nowans[i], b[j] / gd * a[j] / gd), L[j] = (i - 1) * size + 1, R[j] = min(n, i * size);
			}
		}
		for(fint i = 1; i <= n; i++){if(ck(i))vec[b[i]].push_back(belong[i]);}
		for(fint i = 1; i <= M; i++)unique(vec[i].begin(), vec[i].end());
		for(fint i = 1; i <= M; i++){
			for(fint j = i; j <= M; j += i){
				for(fint k : vec[j]){if(!cnt[k])cnt[k] = j;}
			}
			for(fint j = 1; j <= N; j++){
				if(cnt[j]){
					fint qwq = cnt[j] / i;
					ans[j][i] = min(ans[j][i], qwq);
				}
				cnt[j] = 0;
			}
		}
		for(fint i = 1; i <= N; i++){
			for(fint j = 2; j <= M; j++){
				for(fint k : pr[j])ans[i][j] = min(ans[i][j], ans[i][j / k] * k);
			}
		}
		while(q--){
			fint opt = read(), l = read(), r = read();
			if(opt == 1){
				fint x = read();
				fint ql = belong[l], qr = belong[r];
				if(ql == qr){
					if(tag[ql]){for(fint i = L[l]; i < l; i++)a[i] = tag[ql]; for(fint i = r + 1; i <= R[l]; i++)a[i] = tag[ql]; tag[ql] = 0;}
					for(fint i = l; i <= r; i++)a[i] = x;
					work(l);
				}else{
					if(tag[ql]){for(fint i = L[l]; i < l; i++)a[i] = tag[ql]; tag[ql] = 0;}
					if(tag[qr]){for(fint i = r + 1; i <= R[r]; i++)a[i] = tag[qr]; tag[qr] = 0;}
					for(fint i = l; i <= R[l]; i++)a[i] = x;
					for(fint i = L[r]; i <= r; i++)a[i] = x;
					work(l), work(r);
					for(fint i = ql + 1; i < qr; i++){
						nowans[i] = ans[i][x]; tag[i] = x;
					}
				}
			}else{
				fint ql = belong[l], qr = belong[r], all = INF;
				if(ql == qr){
					for(fint i = l; i <= r; i++){all = min(all, sol(i));}
				}else{
					for(fint i = l; i <= R[l]; i++){all = min(all, sol(i));}
					for(fint i = L[r]; i <= r; i++){all = min(all, sol(i));}
					for(fint i = ql + 1; i < qr; i++)all = min(all, nowans[i]);
				}
				cout << all << "\n";
			}
		}
        return 0;
    }
}
signed main(){
    return infinities::main();
}
posted @ 2022-10-25 15:21  infinities  阅读(23)  评论(0编辑  收藏  举报