求助卡常
  • 板块学术版
  • 楼主Qerrj
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/14 22:04
  • 上次更新2024/10/15 11:44:41
查看原帖
求助卡常
360780
Qerrj楼主2024/10/14 22:04

复杂度没有问题,纯纯常数大,孩子卡了一晚上了,求求救救我吧。

CF1609F

#include<bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC target("avx,avx2,sse,sse2")
#define pb push_back
#define il inline
using namespace std;
const int N = 1e6 + 10;
using ll = long long;
int n, stk[N], top, L[N], R[N], c[N];
struct Node{ int mx, cnt, tag; }t[N << 2];
#define ls (p << 1)
#define rs (p << 1 | 1)
#define lc ls, l, mid
#define rc rs, mid + 1, r
#define mid (l + r >> 1)
il void upd(int p, int z) { t[p].mx += z; t[p].tag += z; }
il void down(int p) {
	upd(ls, t[p].tag);
	upd(rs, t[p].tag);
	t[p].tag = 0;
}
il void up(int p) {
	t[p].mx = max(t[ls].mx, t[rs].mx);
	t[p].cnt = (t[ls].mx == t[p].mx) ? t[ls].cnt : 0;
	t[p].cnt += (t[rs].mx == t[p].mx) ? t[rs].cnt : 0;
}
il void bld(int p = 1, int l = 1, int r = n) {
	t[p] = {0, r - l + 1, 0};
	if(l == r) return;
	bld(lc); bld(rc); up(p);
}
il void mdf(int x, int y, int z, int p = 1, int l = 1, int r = n) {
	if(x <= l && r <= y) return upd(p, z);
	down(p); 
	if(x <= mid) mdf(x, y, z, lc);
	if(mid < y) mdf(x, y, z, rc); 
	up(p);
}
vector<array<int, 4>> vec[60];
ll ans, a[N]; 
il void init() {
	for(int i = 1; i <= n; i++) {
		while(top && a[stk[top]] < a[i]) R[stk[top]] = i - 1, top--;
		L[i] = stk[top] + 1;
		stk[++top] = i;
	}
	while(top) R[stk[top--]] = n;
	for(int i = 1; i <= n; i++) {
		vec[c[i]].push_back({L[i], i, R[i], 1});
		vec[c[i]].push_back({i + 1, i, R[i], -1});
	}
}
il char gc() {
	static char buf[1000000], *p1 = buf, *p2 = buf;
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
il ll read() {
	ll x = 0; char c = gc();
	while(!isdigit(c)) c = gc();
	while(isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = gc();
	return x;
}
signed main() {
	n = read(); 
	for(int i = 1; i <= n; i++) a[i] = read(), c[i] = __builtin_popcountll(a[i]);
	init(); for(int i = 1; i <= n; i++) a[i] = -a[i]; init();
	for(int b = 0; b <= 59; b++) { 
		if(vec[b].empty()) continue;
		bld(); sort(begin(vec[b]), end(vec[b]));
		for(int i = 1, j = 0; i <= n; i++) {
			while(j < vec[b].size() && vec[b][j][0] <= i) 
				mdf(vec[b][j][1], vec[b][j][2], vec[b][j][3]), j++;
			ans += t[1].mx == 2 ? t[1].cnt : 0;
		}
	}
	printf("%lld", ans);
	return 0;
}
2024/10/14 22:04
加载中...