分治做法求救
查看原帖
分治做法求救
519384
Link_Cut_Y楼主2023/11/8 18:10

rt。今天模拟赛赛题。O(nlog⁡2V)O(n \log ^ 2 V) 能跑过,但是 O(nlog⁡nlog⁡2V)O(n \log n \log ^ 2 V) 跑不动。看题解里面二分也是这个复杂度但是跑过去了。是代码常数问题吗?

#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#define int long long
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
#define rop(i, a, b) for (int i = (a); i < (b); i ++ )
#define dep(i, a, b) for (int i = (a); i >= (b); i -- )
#define dop(i, a, b) for (int i = (a); i > (b); i -- )

#define Darr(a, L, R) (cerr << #a "[" << L << " ~ " << R << "] = "; rep(x, L, R) cerr << a[x] << " "; cerr << '\n';)
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define D(x) (cerr << #x << " = " << x << '\n')
#define vit vector<int>::iterator
#define all(x) x.begin(), x.end()
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
#define chkmin(a, b) (a = min(a, b))
#define chkmax(a, b) (a = max(a, b))
#define clr(x) (memset(x, 0, sizeof x))
#define sit set<int>::iterator
#define lowbit(x) (x & -x)
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define pi acos(-1)
#define gc getchar
#define pc putchar
#define db double
#define x first
#define y second

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<db, db> PDD;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};
const int mod = 998244353;
const int eps = 1e-9;

void print(int x) { dep(i, 20, 0) pc(((x >> i) & 1) ? '1' : '0'); }
int qpow(int a, int b = mod - 2) {
	int ans = 1; for (; b; b >>= 1, a = 1ll * a * a % mod)
		if (b & 1) ans = 1ll * ans * a % mod; return ans;
}
int mul(int a, int b) {
	int ans = 0; for (; b; b >>= 1, a = (LL)(a + a) % mod)
		if (b & 1) ans = (LL)(ans + a) % mod; return ans;
}
void getline(char *s) {
	char ch = gc(); char *beg = s;
	for (; ch != '\n' && ch != '\r'; (*beg ++ ) = ch, ch = getchar());
}
struct modint {
	int x;
	modint() { x = 0; }
	modint(int x) : x(x) {}
	int Mod(int a, int b) {
		LL s = 1ll * a + 1ll * b;
		return (s < 0 ? s + mod : (s >= mod? s - mod : s));
	}
	modint operator < (const modint &t)const { return x < t.x; }
	modint operator > (const modint &t)const { return x > t.x; }
	modint operator == (const modint &t)const { return x == t.x; }
	modint operator + (modint &t) { modint s(Mod(x, t.x)); return s; }
	modint operator - (modint &t) { modint s(Mod(x, -t.x)); return s; }
	modint operator * (modint &t) { modint s(1ll * x * t.x % mod); return s; }
	modint operator / (modint &t) { modint s(1ll * x * qpow(t.x) % mod); return s; }
};
void read() { return; }
template <typename T, typename ...T2>
void read(T &s, T2 &...oth) {
	s = 0; char ch = gc(); bool f = 0;
	for (; ch < '0' or ch > '9'; ch = gc()) if (ch == '-') f = 1;
	for (; ch >= '0' and ch <= '9'; ch = gc()) s = (s << 1) + (s << 3) + (ch ^ 48);
	s = f ? -s : s; read(oth...); return;
}
void write(char ch) { return; }
template <typename T, typename ...T2>
void write(char ch, T s, T2 ...oth) {
	if (!s) { pc('0'); pc(ch); write(ch, oth...); return; }
	int stk[100], top = 0;
	if (s < 0) pc('-'), s = ~s + 1;
	while (s) stk[ ++ top] = s % 10, s /= 10;
	do pc(stk[top -- ] + (1 << 4) + (1 << 5)); while (top);
	pc(ch); write(ch, oth...); return;
}
const int N = 1000010;
int n, k, d[N], w[N], s[N];
int gcd(int a, int b) {
	return !b ? a : gcd(b, a % b);
}
int solve(int l, int r) {
	if (r - l + 1 < k) return 0;
	if (l == r) return w[l] * w[l];
	int mid = l + r >> 1; int ans = 0;
	ans = max(solve(l, mid), solve(mid + 1, r));
	d[mid] = w[mid]; dep(i, mid - 1, l) d[i] = gcd(d[i + 1], w[i]);
	d[mid + 1] = w[mid + 1]; rep(i, mid + 2, r) d[i] = gcd(d[i - 1], w[i]);
	vector<PII> L, R;
	dep(i, mid, l) if (d[i] != d[i - 1]) L.push_back({i, d[i]});
	rep(i, mid + 1, r) if (d[i] != d[i + 1]) R.push_back({i, d[i]});
	reverse(L.begin(), L.end()); int now = 0;
	rop(i, 0, L.size()) {
		while (now < R.size() and R[now].x - L[i].x + 1 < k) now ++ ;
		if (now == R.size()) break;
		rop(j, now, R.size()) ans = max(ans, gcd(L[i].y, R[j].y) * (s[R[j].x] - s[L[i].x - 1]));
	} return ans;
}
signed main() {
    read(n, k);
    rep(i, 1, n) read(w[i]);
    rep(i, 1, n) s[i] = s[i - 1] + w[i];
    write('\n', solve(1, n)); return 0;
}
2023/11/8 18:10
加载中...