*题解:P12013 [Ynoi April Fool's Round 2025] 牢夸

题目链接

解析

考虑允许 \(L=R\) 怎么做,发现直接取最大值就好,因为最大值跟其它数组合起来求平均值结果并不会变得更大。

现在我们要求长度至少为 \(2\),类似的道理,把若干个长度为 \(2\) 的区间组合起来必定不优,也就是说只要考虑长度为 \(2\) 的区间就相当于考虑了所有长度为偶数的区间。进一步地,再考虑长度为 \(3\) 的区间,与长度为 \(2\) 的区间相结合就相当于考虑了所有的区间。

故将相邻的两个数/三个数合并到一起,开两个线段树分别维护 \(a_i + a_{i + 1}\)\(a_i + a_{i + 1} + a_{i + 2}\) 的最大值即可。

代码

#include<bits/stdc++.h>
#define ls(x) ((x) << 1)
#define rs(x) (((x) << 1) | 1)
#define mid ((l + r) >> 1)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> pii;
const int N = 1e6 + 5,M = 60,K = 10000 + 5,mod = (int)1e9 + 7;
ll a[N],a2[N],a3[N];
struct T{
	ll mx[N << 2],tag[N << 2];
	void push_up(int p){
		mx[p] = max(mx[ls(p)],mx[rs(p)]);
	}
	void build(int p,int l,int r,ll *a){
		if(l > r) return;
		if(l == r){
			mx[p] = a[l];
			return;
		}
		build(ls(p),l,mid,a),build(rs(p),mid + 1,r,a);
		push_up(p);
	}
	void add_tag(int p,ll x){
		tag[p] += x;
		mx[p] += x;
	}
	void push_down(int p){
		if(!tag[p]) return;
		add_tag(ls(p),tag[p]),add_tag(rs(p),tag[p]);
		tag[p] = 0;	
	}
	void add(int p,int l,int r,int L,int R,ll k){
		if(l > R || r < L) return;
		if(l >= L && r <= R){
			add_tag(p,k);
			return;
		}
		push_down(p);
		add(ls(p),l,mid,L,R,k),add(rs(p),mid + 1,r,L,R,k);
		push_up(p);
	}
	ll ask(int p,int l,int r,int L,int R){
		if(l > R || r < L) return -1e17;
		if(l >= L && r <= R){
			return mx[p];
		}
		push_down(p);
		return max(ask(ls(p),l,mid,L,R),ask(rs(p),mid + 1,r,L,R));
	}
}t1,t2;
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);	
//	freopen("in.txt","r",stdin);
//	freopen("out1.txt","w",stdout);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<n;i++){
		a2[i] = a[i] + a[i + 1];
	}
	for(int i=1;i<=n - 2;i++){
		a3[i] = a[i] + a[i + 1] + a[i + 2];
	}
	t1.build(1,1,n - 1,a2);
	t2.build(1,1,n - 2,a3);
	while(m--){
		int op,l,r,x;
		cin>>op>>l>>r;
		if(op == 1){
			cin>>x;
			
			t1.add(1,1,n - 1,l,r - 1,x * 2);
			t1.add(1,1,n - 1,r,r,x);
			t1.add(1,1,n - 1,l - 1,l - 1,x);
			
			t2.add(1,1,n - 2,l,r - 2,x * 3);
			int len = r - l + 1;
			if(len >= 2){
				t2.add(1,1,n - 2,r - 1,r - 1,x * 2);
				t2.add(1,1,n - 2,l - 1,l - 1,x * 2);
			}else{
				t2.add(1,1,n - 2,l - 1,l - 1,x);
			}
			t2.add(1,1,n - 2,r,r,x);
			t2.add(1,1,n - 2,l - 2,l - 2,x);
		}else{
			ll v1 = t1.ask(1,1,n - 1,l,r - 1),v2 = t2.ask(1,1,n - 2,l,r - 2);
			if(v1 * 3 > v2 * 2){
				if(v1 % 2 == 0){
					cout<<v1 / 2<<"/"<<1<<'\n';
				}else{
					cout<<v1<<"/"<<2<<'\n';
				}
			}else{
				if(v2 % 3 == 0){
					cout<<v2 / 3<<"/"<<1<<'\n';
				}else{
					cout<<v2<<"/"<<3<<'\n';
				}
			}
		}
	}
	return 0;
}
posted @ 2026-08-30 12:31  yutar  阅读(4)  评论(0)    收藏  举报