Codeforces Round 830
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();
}