洛谷 P10516 数据结构 Solution

Description

给定序列 a=(a1,a2,⋯ ,an)a=(a_1,a_2,\cdots,a_n)a=(a1,a2,,an)b=(b1,b2,⋯ ,bn)b=(b_1,b_2,\cdots,b_n)b=(b1,b2,,bn),有 mmm 个操作分三种:

  • add⁡(l,r,k,t)\operatorname{add}(l,r,k,t)add(l,r,k,t):对每个 i∈[l,r]i\in[l,r]i[l,r],若 ai×bi≤ka_i\times b_i\le kai×bik,则执行 ai←ai+t,bi←bi+ta_i\gets a_i+t,b_i\gets b_i+taiai+t,bibi+t.
  • set⁡(i,x,y)\operatorname{set}(i,x,y)set(i,x,y):执行 ai←x,bi←ya_i\gets x,b_i\gets yaix,biy.
  • query⁡(l,r)\operatorname{query}(l,r)query(l,r):求 ∑i=lrai+bi\sum\limits_{i=l}^r a_i+b_ii=lrai+bi.

Limitations

1≤n,m≤1051 \le n,m \le 10^51n,m105
0≤ai,bi,k,t,x,y≤1050 \le a_i,b_i,k,t,x,y \le 10^50ai,bi,k,t,x,y105
2s,512MB2\text{s},512\text{MB}2s,512MB

Solution

若没有 add⁡\operatorname{add}add 操作是容易维护的.
对于 add⁡\operatorname{add}add,若 t=0t=0t=0 直接忽略;否则 t>0t>0t>0,易得一个数至多连续进行 k\sqrt kkadd⁡\operatorname{add}add.
由于初始的 aaaset⁡\operatorname{set}set 操作至多带来约 (n+q)(n+q)(n+q) 个数,故 add⁡\operatorname{add}add 至多影响 (n+q)k(n+q)\sqrt k(n+q)k 个数.
于是可在线段树上维护 ai×bia_i\times b_iai×bi 的最小值,若 kkk 大于最小值则直接返回,否则递归修改.
时间复杂度 O((n+q)klog⁡nO((n+q)\sqrt k\log nO((n+q)klogn).

Code

2.63KB,1.39s,17.27MB  (in total, C++20 with O2)2.63\text{KB},1.39\text{s},17.27\text{MB}\;\texttt{(in total, C++20 with O2)}2.63KB,1.39s,17.27MB(in total, C++20 with O2)

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;

template<class T>
bool chmax(T &a, const T &b){
	if(a < b){ a = b; return true; }
	return false;
}

template<class T>
bool chmin(T &a, const T &b){
	if(a > b){ a = b; return true; }
	return false;
}

inline int ls(int u) { return 2 * u + 1; }
inline int rs(int u) { return 2 * u + 2; }

struct Node {
	int l, r;
	i64 a, b, sum, min;
	
	void upd(i64 x, i64 y) { a = x, b = y, sum = x + y, min = x * y; }
};

struct SegTree {
	vector<Node> tr;
	inline SegTree() {}
	inline SegTree(const vector<i64>& a, const vector<i64>& b) {
		const int n = a.size();
		tr.resize(n << 2);
		build(0, 0, n - 1, a, b);
	}
	
	inline void pushup(int u) {
		tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
		tr[u].min = min(tr[ls(u)].min, tr[rs(u)].min);
	}
	
	inline void build(int u, int l, int r, const vector<i64>& a, const vector<i64>& b) {
		tr[u].l = l, tr[u].r = r;
		if (l == r) return tr[u].upd(a[l], b[l]);
		const int mid = (l + r) >> 1;
		build(ls(u), l, mid, a, b);
		build(rs(u), mid + 1, r, a, b);
		pushup(u);
	}
	
	inline void update(int u, int l, int r, i64 k, i64 t) {
		if (tr[u].min > k || t == 0) return;
		if (tr[u].l == tr[u].r) return tr[u].upd(tr[u].a + t, tr[u].b + t);
		const int mid = (tr[u].l + tr[u].r) >> 1;
		if (l <= mid) update(ls(u), l, r, k, t);
		if (r > mid) update(rs(u), l, r, k, t);
		pushup(u);
	}
	
	inline void set(int u, int p, i64 s, i64 t) {
		if (tr[u].l == tr[u].r) return tr[u].upd(s, t);
		const int mid = (tr[u].l + tr[u].r) >> 1;
		if (p <= mid) set(ls(u), p, s, t);
		else set(rs(u), p, s, t);
		pushup(u);
	}
	
	inline i64 sum(int u, int l, int r) {
		if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
		const int mid = (tr[u].l + tr[u].r) >> 1;
		i64 res = 0;
		if (l <= mid) res += sum(ls(u), l, r);
		if (r > mid) res += sum(rs(u), l, r);
		return res;
	}
};

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int n, m;
	scanf("%d %d", &n, &m);
	vector<i64> a(n), b(n);
	for (int i = 0; i < n; i++) scanf("%lld", &a[i]);
	for (int i = 0; i < n; i++) scanf("%lld", &b[i]);
	
	SegTree seg(a, b);
	for (int i = 0, op; i < m; i++) {
		scanf("%d", &op);
		if (op == 1) {
			int l, r; i64 k, t;
			scanf("%d %d %lld %lld", &l, &r, &k, &t), l--, r--;
			seg.update(0, l, r, k, t);
		}
		else if (op == 2) {
			int p; i64 s, t;
			scanf("%d %lld %lld", &p, &s, &t), p--;
			seg.set(0, p, s, t);
		}
		else {
			int l, r;
			scanf("%d %d", &l, &r), l--, r--;
			printf("%lld\n", seg.sum(0, l, r));
		}
	}
	
	return 0;
}
<think>好的,我需要帮助用户查找P9244题目的解析或代码实现。首先,用户提到的引用内容是关于其他题目的,比如P2241、P2089、P1152,但并没有提到P9244。这说明用户提供的引用资料里可能没有直接相关的信息。 接下来,我应该检查用户给出的引用内容是否有任何与P9244相关的内容。根据引用1到4,都是关于不同题目的题解,比如统计方形、烤鸡、欢乐的跳等,但没有提到P9244。因此,可能需要建议用户通过其他途径查找,比如官网或相关论坛。 另外,用户可能需要指导如何自行查找P9244的解析。可以建议他们使用的搜索功能,或者查看题目的讨论区。还可以提到常见的解题方法,比如枚举、动态规划、数据结构应用等,作为可能的解题方向。 需要注意的是,回答要结构清晰,用中文,并遵循格式要求,比如数学表达式用$...$,独立公式用$$...$$。同时生成相关问题,帮助用户进一步探索。 总结步骤: 1. 指出当前引用中没有P9244的信息。 2. 建议用户通过官网或社区查找。 3. 提供一般性的解题策略。 4. 生成相关问题,帮助用户深入解题。</think>根据您提供的引用内容,目前未发现与P9244题目直接相关的解析或代码实现。不过基于题目的分类特点,以下提供通用的解题思路和资源查找建议: ### 一、题目解析通用方法 1. **题目分类识别** 首先需确认P9244的标签类型(如数学、图论、动态规划等)。例如: - 若涉及数学公式推导,可能需使用组合数学公式:$$C(n,k) = \frac{n!}{k!(n-k)!}$$ - 若为图论题,可能涉及最短路径算法如Dijkstra 2. **代码实现框架** 根据题目类型选择算法模板: ```python # 动态规划示例框架 def dp_solution(n): dp = [0]*(n+1) dp[0] = 1 for i in range(1, n+1): dp[i] = dp[i-1] + dp[i-2] return dp[n] ``` ### 二、资源查找建议 1. **官方题解** 登录题目页面,查看「讨论」或「题解」板块,通常会有用户提交的解析[^1] 2. **搜索引擎技巧** 使用精确搜索:`"P9244" site:luogu.com.cn` 3. **算法竞赛社区** 在Codeforces、优快云等平台搜索题目编号,可能找到相关分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值