QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#645221#8577. 평균 최대화user100860 355ms143688kbC++239.9kb2024-10-16 17:18:482024-10-16 17:18:54

Judging History

你现在查看的是最新测评结果

  • [2024-10-16 17:18:54]
  • 评测
  • 测评结果:0
  • 用时:355ms
  • 内存:143688kb
  • [2024-10-16 17:18:48]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 3e5 + 10;

int n, idx, l[N], r[N], a[N], s[N], rx[N], rs[N];

//  #define __int128 int

int pc;
__int128 gcd(__int128 a, __int128 b)
{
    if (a == 0) return b;
    if (b == 0) return a;

    int az = __builtin_ctzll(a & 0xffffffffffffffff);
    int bz = __builtin_ctzll(b & 0xffffffffffffffff);
    int shift = min(az, bz);
    b >>= bz;
    
    while (a != 0) {
        a >>= az;
        __int128 diff = b - a;
        az = __builtin_ctzll(diff & 0xffffffffffffffff);
        b = min(a, b);
        a = diff < 0 ? -diff : diff; 
    }
    
    return b << shift;
}

struct F
{
	__int128 i, j;
	
	F()
	{
		i = j = 0;
	}
	
	F(__int128 a, __int128 b)
	{
		i = a, j = b;
 		__int128 d = gcd(i, j);
 		i /= d, j /= d;
	}
	
	bool operator> (const F& f2) const
	{
		return i * f2.j > j * f2.i;
	}
	
	bool operator< (const F& f2) const
	{
		return i * f2.j < j * f2.i;
	}
	
	F operator + (const F& f2) const
	{
		return {i * f2.j + j * f2.i, j * f2.j};
	}
	
}ans[N];

struct V
{
	__int128 x, y;
	
	V operator+ (const V& v2) const
	{
		return {x + v2.x, y + v2.y};
	}
	
	bool operator< (const V& v2) const
	{
		return y * v2.x < x * v2.y;
	}
	
	bool operator> (const V& v2) const
	{
		return y * v2.x > x * v2.y;
	}
};

mt19937 rng(20241015);
namespace Tree
{
	const int R = 2;
	int idx;
	int ls[N * R], rs[N * R], sz[N * R];
	V val[N * R], sum[N * R];
	
	void init()
	{
		val[0] = sum[0] = {0, 0};
	}
	
	int newnode(V v)
	{
		idx++;
		assert(idx < N * R);
		ls[idx] = rs[idx] = 0, sz[idx] = 1;
		val[idx] = sum[idx] = v;
		return idx;
	}
	
	inline void pushup(int u)
	{
		if (!u) return;
		sum[u] = sum[ls[u]] + val[u] + sum[rs[u]];
		sz[u] = sz[ls[u]] + 1 + sz[rs[u]];
	}
	
//	inline void apply(int u, const F& dass)
//	{
//		if (!u) return;
//		sum[u] = {dass.i * sz[u], dass.j}, val[u] = dass;
//		tass[u] = dass;
//	}
//	
//	inline void pushdown(int u)
//	{
//		if (!u) return;
//		if (tass[u].i == 0) return;
//		apply(ls[u], tass[u]), apply(rs[u], tass[u]);
//		tass[u] = {0, 1};
//	}
	
	array<int, 2> splitr(int u, int k)
	{
		// [1, k], [k+1, inf)
//		printf("splitr(%lld, %lld)\n", u, k);
		if (!u) return {0, 0};
		if (sz[ls[u]] >= k)
		{
			auto res = splitr(ls[u], k);
			ls[u] = res[1];
			pushup(u);
			return {res[0], u};
		}
		else
		{
			auto res = splitr(rs[u], k - sz[ls[u]] - 1);
			rs[u] = res[0];
			pushup(u);
//			printf("&&&");
			return {u, res[1]};
		}
	}
	
	array<int, 2> splitv(int u, const V& v)
	{
		// [1, v] [v, inf)
		if (!u) return {0, 0};
		if (v > val[u])
		{
			auto res = splitv(ls[u], v);
			ls[u] = res[1];
			pushup(u);
			return {res[0], u};
		}
		else
		{
			auto res = splitv(rs[u], v);
			rs[u] = res[0];
			pushup(u);
			return {u, res[1]};
		}
	}
	
	int merge(int l, int r)
	{
//		printf("merge(%lld, %lld)\n", l, r);
		if (!l) swap(l, r);
		if (!r) return l;
		
		if (rng() % (sz[l] + sz[r]) < sz[l])
		{
			rs[l] = merge(rs[l], r);
			pushup(l);
			return l;
		}
		else
		{
			ls[r] = merge(l, ls[r]);
			pushup(r);
			return r;
		}
	}
	
	inline void insert(int& rt, const V& v)
	{
		auto res = splitv(rt, v);
		int c = newnode(v);
		rt = merge(merge(res[0], c), res[1]);
	}
	
//	inline void assign(int& rt, int pos, const F& v)
//	{
//		auto res = splitr(rt, pos);
//		apply(res[0], v);
//		rt = merge(res[0], res[1]);
//	}
	
//	inline F qsum(int rt, int pos)
//	{
//	    if (!rt) return {0, 1};
//	    pushdown(rt);
//	    if (pos <= sz[ls[rt]]) return qsum(ls[rt], pos);
//	    else return sum[ls[rt]] + val[rt] + qsum(rs[rt], pos - sz[ls[rt]] - 1);
//// 		auto res = splitr(rt, pos);
////		printf("qsum(%lld, %lld)\n", rt, pos);
//// 		F ret = sum[res[0]];
//// 		rt = merge(res[0], res[1]);
//// 		return ret;
//	}
//	
//	const F& kth(int rt, int k)
//	{
//	    int p = sz[ls[rt]];
//	    pushdown(rt);
//	    if (k <= p) return kth(ls[rt], k);
//	    else if (k > p + 1) return kth(rs[rt], k - sz[ls[rt]] - 1);
//	    else return val[rt];
//// 		auto res = splitr(rt, k);
//// 		auto res2 = splitr(res[0], k - 1);
//// 		F ret = val[res2[1]];
//// 		rt = merge(merge(res2[0], res2[1]), res[1]);
//// 		return ret;	
//	}
	
 	void print(int rt)
 	{
 		if (!rt) return;
 		print(ls[rt]), printf("node %lld: sum = %lld/%lld, val = %lld/%lld, ls = %lld, rs = %lld\n", rt, sum[rt].y, sum[rt].x, val[rt].y, val[rt].x, ls[rt], rs[rt]), print(rs[rt]);
 	}

	void pop(int& rt)
	{
		auto res = splitr(rt, 1);
		rt = res[1];
	}
	
	V front(int& rt)
	{
		auto res = splitr(rt, 1);
		V ret = val[res[0]];
		rt = merge(res[0], res[1]);
		return ret;
	}
}

int pc2;
int dp[N];
vector<int> son[N];
vector<int> rg[N];
map<array<int, 2>, int> mp;

int build(int l, int r)
{
	idx++, ::l[idx] = l, ::r[idx] = r, mp[{l, r}] = idx;
	int x = idx; rx[x] = r - l + 1, rs[x] = s[r] - s[l - 1];
	for (int i = l; i <= r; i++)
	{
		if (rg[i].empty()) continue;
		int j = rg[i].back(); rg[i].pop_back();
		int y = build(i, j);
		son[x].push_back(y);
		rx[x] -= (j - i + 1), rs[x] -= (s[j] - s[i - 1]);
		i = j;
	}
	return x;
}

template<class T>
void chkmax(T &x, T y)
{
	if (y > x) x = y;
}

void merge(int& a, int b)
{
	if (!b) return;
	merge(a, Tree::ls[b]), merge(a, Tree::rs[b]);
	Tree::ls[b] = Tree::rs[b] = 0, Tree::sz[b] = 1, Tree::sum[b] = Tree::val[b];
	auto res = Tree::splitv(a, Tree::val[b]);
	a = Tree::merge(Tree::merge(res[0], b), res[1]);
}

void getp(int rt, int a, int b, V cur, int rk, V& ans)
{
//	printf("getp(%lld, %lld, %lld, {%lld, %lld}, %lld)\n", rt, a, b, cur.i, cur.j, rk);
    if (!rt) return;
    V f = cur + Tree::sum[Tree::ls[rt]], d = Tree::val[rt];
    f.y -= b, f.x -= a;
//    printf("f\' = {%lld, %lld}, d = {%lld, %lld}\n", f.i, f.j, d.i, d.j);
    if (f > d) getp(Tree::ls[rt], a, b, cur, rk, ans);
    else
    {
        ans = cur + Tree::sum[Tree::ls[rt]] + Tree::val[rt];
        getp(Tree::rs[rt], a, b, cur + Tree::sum[Tree::ls[rt]] + Tree::val[rt], rk + Tree::sz[Tree::ls[rt]] + 1, ans);
    }
}

// pair<int, F> getp(int rt, int a, int b)
// {
// 	// max (y - b) / (x - a)
// 	int l = 0, r = Tree::sz[rt];
// 	auto getres = [&](int x)
// 	{
// 		F y1 = Tree::qsum(rt, x);
// 		y1.i -= b * y1.j, y1.j *= (x - a);
// //		y1.reduce();
// 		return y1;
// 	};
// 	int dpc = 0;
// 	while (l < r)
// 	{
// //		int mid1 = (l + r) >> 1, mid2 = mid1 + 1;
//         dpc += 2;
// 		int mid = (l + r) >> 1;
// 		F f = Tree::qsum(rt, mid), d = Tree::kth(rt, mid + 1);
// 		f.i -= b * f.j, f.j *= (mid - a);
// 		if (f > d) r = mid;
// 		else l = mid + 1;
// 	}
// //	printf(")))"), Tree::print(rt);
// //	printf("res(l) = (%lld, %lld/%lld), res(r) = (%lld, %lld/%lld)\n", l, getres(l).i, getres(l).j, r, getres(r).i, getres(r).j);
// 	dpc++;
// 	assert(dpc < 19 * 2 + 1);
// 	pc2 += dpc;
// 	auto resl = getres(l);
// 	return {l, resl};
// }

void dfs(int x)
{
//	printf("dfs(%lld)\n", x);
	dp[x] = 0;
	if (son[x].empty()) Tree::insert(dp[x], {rx[x], rs[x]});
	else 
	{
		for (int y : son[x]) 
		{
			dfs(y);
			if (Tree::sz[dp[x]] < Tree::sz[dp[y]]) swap(dp[x], dp[y]);
			merge(dp[x], dp[y]);
		}
		if (x == 1) return;
//		Tree::print(dp[x]);
//		 (-rx[x], -rs[x])
//printf("getp(%lld)\n", x);
		V res = {0, 0};
		getp(dp[x], -rx[x], -rs[x], {0, 0}, 0, res);
//		printf("proc: res = {%lld, %lld}\n", res.y, res.x);
		while (Tree::sz[dp[x]] && !(Tree::front(dp[x]) < res)) Tree::pop(dp[x]);
		res.x += rx[x], res.y += rs[x];
		Tree::insert(dp[x], res);
//		int p = res.first;
//		F v = res.second;
//		Tree::assign(dp[x], p, v);
//		for (int i = 1; i <= rx[x]; i++) Tree::insert(dp[x], v);
	}
//	Tree::print(dp[x]);
//	cout << "***";
//	assert(pc < 3.5e7);
	V res = {0, 0};
	getp(dp[x], -2, -(a[l[x] - 1] + a[r[x] + 1]), {0, 0}, 0, res);
	res.x += 2, res.y += (a[l[x] - 1] + a[r[x] + 1]);
	ans[x] = {res.y, res.x};
//	printf("%lld: (%lld, %lld)\n", x, ans[x].i, ans[x].j);
}

bool flag;

void initialize(vector<signed> A)
{
    n = (int)(A.size());
    for (int i = 1; i <= n; i++) a[i] = A[i - 1];
	for (int i = 1; i <= n; i++) s[i] = a[i] + s[i - 1];
    vector<int> s;
    for (int i = n; i >= 1; i--)
    {
    	while (!s.empty() && a[s.back()] > a[i])
    	{
    		int x = s.back(); s.pop_back();
    		if (x != i + 1) rg[i + 1].push_back(x - 1);
    	}
    	if (!s.empty() && s.back() != i + 1) rg[i + 1].push_back(s.back() - 1); 
    	if (!s.empty() && a[s.back()] >= a[i]) s.pop_back();
    	s.push_back(i);
    }
//	for (int i = 1; i <= n; i++)
//		for (int j : rg[i]) printf("[%lld, %lld]\n", i, j);
    
    build(2, n - 1);
//    for (int i = 1; i <= n; i++)
//    	printf("rx[%lld] = %lld, rs[%lld] = %lld\n", i, rx[i], i, rs[i]);
    Tree::init();
    if (!flag) dfs(1);
    
//    for (int i = 1; i <= n; i++)
//    	for (int j = 0; j <= sz[i]; j++)
//    		printf("dp[%lld][%lld] = %lld\n", i, j, dp[i][j]);
    
//    for (int i = 1; i <= n; i++)
//    	for (int j : son[i]) printf("[%lld, %lld] -> [%lld, %lld]\n", l[i], r[i], l[j], r[j]);
}

array<long long, 2> maximum_average(signed i, signed j)
{
	i++, j++;
	if (j == i + 1) return {a[i] + a[j], 2};
	assert(mp.find({i + 1, j - 1}) != mp.end());
	int id = mp[{i + 1, j - 1}];
	if (flag) return {idx, ans[id].j};
	return {ans[id].i, ans[id].j};
}

// signed main()
// {
// 	cin.tie(0)->sync_with_stdio(0);
//	
// 	int n; cin >> n;
// 	vector<signed> A;
//  	for (int i = 1, ai; i <= n; i++) cin >> ai, A.push_back(ai); 
//// 	for (int i = 1, ai; i <= n; i++) A.push_back(rng() % 20 + 1);
// 	initialize(A);
// 	printf("idx = %lld, pc = %lld, pc2 = %lld, time = %lld\n", idx, pc, pc2, (int)clock());
// 	int l, r;
// 	while (cin >> l >> r)
// 	{
// 		auto res = maximum_average(l, r);
// 		cout << res[0] << ' ' << res[1] << '\n';
// 	}
// }

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 5
Accepted
time: 0ms
memory: 36536kb

input:

10
2 4 3 9 9 9 9 9 9 1
2
0 2
0 9

output:

3 1
20 3

result:

ok correct!

Test #2:

score: 5
Accepted
time: 0ms
memory: 34548kb

input:

15
4596730 8340349 4612555 5692442 3914918 5213545 5248236 1276073 3844119 2943960 9231647 5091649 2239006 9139001 4735414
100
7 8
5 6
2 4
0 4
8 9
10 11
3 4
0 1
10 11
10 11
3 4
4 5
12 13
0 2
2 4
11 12
12 14
2 3
7 8
12 14
6 7
4 5
11 12
10 11
7 12
8 9
8 9
0 2
2 3
12 14
7 9
7 9
12 13
10 11
9 11
13 14
8...

output:

5120192 2
10461781 2
14219915 3
27156994 5
6788079 2
14323296 2
9607360 2
12937079 2
14323296 2
14323296 2
9607360 2
9128463 2
11378007 2
5849878 1
14219915 3
7330655 2
16113421 3
10304997 2
5120192 2
16113421 3
6524309 2
9128463 2
7330655 2
14323296 2
4156467 1
6788079 2
6788079 2
5849878 1
1030499...

result:

ok correct!

Test #3:

score: 0
Wrong Answer
time: 105ms
memory: 36896kb

input:

15
962724 8815662 7612372 5708998 125165 5107756 9366378 9514244 2381600 4299006 9423670 8225791 7458292 2315903 7210561
600000
7 8
0 4
6 8
9 10
11 12
4 5
13 14
8 13
9 11
2 3
7 8
9 12
6 8
0 4
0 2
12 13
1 2
8 13
0 3
9 10
4 5
6 7
6 8
6 7
0 2
4 13
3 4
6 7
8 9
6 7
11 12
5 8
0 3
9 13
4 8
4 8
8 9
8 13
4 1...

output:

11895844 2
23224921 5
21262222 3
13722676 2
15684083 2
5232921 2
9526464 2
17052131 3
21948467 3
13321370 2
11895844 2
29406759 4
21262222 3
23224921 5
17390758 3
9774195 2
16428034 2
17052131 3
5774939 1
13722676 2
5232921 2
18880622 2
21262222 3
18880622 2
17390758 3
43812282 7
5834163 2
18880622 ...

result:

wrong answer Wrong Answer on query #26: 43812282/7 != 58217805/10

Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Wrong Answer

Test #15:

score: 0
Wrong Answer
time: 120ms
memory: 60700kb

input:

300000
1 2 4 4 4 4 3 2 4 4 3 4 4 4 4 4 4 4 4 4 3 4 3 4 4 4 4 4 4 4 4 3 3 4 4 4 3 4 3 4 4 4 4 4 4 4 4 4 4 3 3 4 4 4 3 4 4 3 4 4 4 4 4 4 4 3 2 4 4 4 4 4 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 4 4 4 4 4 2 4 4 2 4 4 3 4 4 4 2 3 4 4 4 4 4 4 3 2 4 4 4 2 4 4 4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 4 3 4 4 3 4 4 4 4 4 4 4 4 4...

output:

16592 4287
23 7
3 2
8 2
6 2
8 2
8 2
7 2
5 2
7 2
56 15
8 2
6 2
7 2
42 11
13 4
8 2
7 2
8 2
8 2
8 2
8 2
8 2
8 2
8 2
7 2
10 3
7 2
7 2
19 5
8 2
7 2
8 2
8 2
8 2
8 2
8 2
8 2
7 2
6 2
18 5
8 2
7 2
8 2
7 2
10 3
7 2
7 2
23 6
8 2
7 2
8 2
8 2
8 2
8 2
8 2
8 2
8 2
8 2
7 2
6 2
18 5
8 2
7 2
8 2
7 2
7 2
8 2
7 2
7 2
3...

result:

wrong answer Wrong Answer on query #1: 16592/4287 != 1041675/278497

Subtask #5:

score: 0
Skipped

Dependency #3:

0%

Subtask #6:

score: 0
Time Limit Exceeded

Test #28:

score: 17
Accepted
time: 273ms
memory: 143688kb

input:

300000
1 300000 300001 299999 300003 299998 300005 299997 300007 299996 300009 299995 300011 299994 300013 299993 300015 299992 300017 299991 300019 299990 300021 299989 300023 299988 300025 299987 300027 299986 300029 299985 300031 299984 300033 299983 300035 299982 300037 299981 300039 299980 3000...

output:

458625151 1225

result:

ok correct!

Test #29:

score: 17
Accepted
time: 355ms
memory: 87612kb

input:

262143
1 36 17 55 17 36 16 94 16 36 17 55 17 36 15 173 15 36 17 55 17 36 16 94 16 36 17 55 17 36 14 332 14 36 17 55 17 36 16 94 16 36 17 55 17 36 15 173 15 36 17 55 17 36 16 94 16 36 17 55 17 36 13 651 13 36 17 55 17 36 16 94 16 36 17 55 17 36 15 173 15 36 17 55 17 36 16 94 16 36 17 55 17 36 14 332 ...

output:

1310726 5

result:

ok correct!

Test #30:

score: 0
Time Limit Exceeded

input:

30000
1 8655519 5053769 2 3 4 5 6991720 3321347 8718018 4464302 8356978 6 7 8 8314637 5910310 3734266 7192139 9183941 9 4352483 6266035 4417558 10 6855725 6999520 4363735 11 12 3499845 8360666 13 14 15 16 9638440 7317746 17 9282787 18 7466678 7930596 9367029 9821794 19 9771448 5441062 6451096 328952...

output:

Unauthorized output

result:


Subtask #7:

score: 0
Skipped

Dependency #4:

0%

Subtask #8:

score: 0
Skipped

Dependency #1:

0%