首页 > 其他分享 >【友谊就是魔法!!】CF453E

【友谊就是魔法!!】CF453E

时间:2024-01-26 16:37:17浏览次数:20  
标签:Info int 友谊 魔法 sumr ret lim CF453E suma

Friendship is magic!!

前置简单题: [ABC255Ex] Range Harvest Query

考虑维护 \(t\) 相同的颜色段。

然后注意到一个颜色段被取出后必然被推平,所以一个段只会被遍历一次。

一次只会增加一个颜色段,可以 \(O(q \log n)\) 来维护。

然后我们考虑对于没有推平过和推平过的分类:

  • 没有推平过:

考虑计算 \(s_i + t \times r_i < m_i\) 的左式总和,然后再计算 \(s_i + t \times r_i > m_i\) 的右式总和。

可以考虑的办法是对于左边大于右边的阈值 \(t_i\) 上二位数点,然后再结合前缀和计算。

具体来说是维护 \(t_i \leq t\) 的所有 \(m_i\) 以及 \(t_i > t\) 的所有 \(s_i\) 和 \(r_i\),然后就可以分类计算贡献。

  • 推平过:
    即原来的 \(s_i \to 0\) 的情况。

不难用两个主席树维护。复杂度 \(O((n + q) \log n)\)。

代码很丑。

// LUOGU_RID: 139435454
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; i ++)
#define per(i, r, l) for (int i = r; i >= l; i --)

using namespace std;
bool s1;

typedef long long ll;
const int _ = 1e5 + 5, lim = 1e5 + 5, mod = 998244353;
int power (int x, int y) {
	int ret = 1;
	for ( ; y; y >>= 1, x = 1ll * x * x % mod)
		if (y & 1) ret = 1ll * ret * x % mod;
	return ret;
}

struct node {
	int l, r, t;
	node (int _l = -1, int _r = -1, int _t = -1) {
		l = _l, r = _r, t = _t;
	}
	bool operator < (const node & x) const { return l < x.l; }
};
set <node> s;
auto split (int x) {
	auto it = s.lower_bound(node(x));
	if (it != s.end() && it -> l == x) return it;
	-- it;
	node tmp(*it);
	s.erase(tmp), s.insert(node(tmp.l, x - 1, tmp.t));
	return s.insert(node(x, tmp.r, tmp.t)).first;
}

int tot[2], rt[_], rtp[_];
namespace dataStructure {
	struct Info { 
		ll sums = 0, suma = 0, sumr = 0;
	} initp;
	Info operator + (Info x, Info y) { return {x.sums + y.sums, x.suma + y.suma, x.sumr + y.sumr}; }
	Info operator - (Info x, Info y) { return {x.sums - y.sums, x.suma - y.suma, x.sumr - y.sumr}; }
	struct SegMent {
		int op;
		int lc[_ * 20], rc[_ * 20];
		Info t[_ * 20];
		void ins (int &x, int p, int l, int r, int v, Info k) {
			x = ++ tot[op], lc[x] = lc[p], rc[x] = rc[p], t[x] = t[p] + k;
			if (l == r) return ;
			int mid = (l + r) >> 1;
			v <= mid ? ins(lc[x], lc[p], l, mid, v, k) : ins(rc[x], rc[p], mid + 1, r, v, k);
		}
		Info query (int x, int l, int r, int ql, int qr) {
			if (!x) return initp;
			if (ql <= l && r <= qr) return t[x];
			int mid = (l + r) >> 1;
			Info ret = initp;
			if (ql <= mid) ret = ret + query(lc[x], l, mid, ql, qr);
			if (qr > mid) ret = ret + query(rc[x], mid + 1, r, ql, qr);
			return ret;
		}
	} t1, t2;
	
} using namespace dataStructure;
int n, q;
int a[_], m[_], r[_];
ll suma[_], sumr[_];

bool s2;
int main () {
	cin >> n;
	t1.op = 0, t2.op = 1;
	rep(i, 1, n) {
		scanf("%d%d%d", & a[i], & m[i], & r[i]);
		
		if (r[i]) {
			int t = (m[i] - a[i]) / r[i];
			if (t * r[i] + a[i] < m[i]) 
				t1.ins(rt[i], rt[i - 1], 0, lim, t + 1, {m[i], a[i], r[i]});
			else 
				t1.ins(rt[i], rt[i - 1], 0, lim, t, {m[i], a[i], r[i]});			
		} else t1.ins(rt[i], rt[i - 1], 0, lim, 0, {a[i], a[i], 0});
		
		sumr[i] = sumr[i - 1] + r[i], suma[i] = suma[i - 1] + a[i];
		
		if (r[i]) {
			int t = m[i] / r[i];
			if (t * r[i] < m[i]) 
				t2.ins(rtp[i], rtp[i - 1], 0, lim, t + 1, {m[i], 0, r[i]});
			else 
				t2.ins(rtp[i], rtp[i - 1], 0, lim, t, {m[i], 0, r[i]});			
		} else t2.ins(rtp[i], rtp[i - 1], 0, lim, 0, {0, 0, 0});
		
	}
	s.insert(node(1, n, 0));
	cin >> q;
	while (q --) {
		int l, r, t;
		ll ret = 0;
		scanf("%d%d%d", & t, & l, & r);
		auto itr = split(r + 1), itl = split(l);
		for (auto it = itl; it != itr; it ++) {
			int l = it -> l, r = it -> r, c = it -> t;
			if (!c) {
				c = t;
				Info res = t1.query(rt[r], 0, lim, 0, c) - t1.query(rt[l - 1], 0, lim, 0, c);
				ret += res.sums;
				ret += 1ll * c * (sumr[r] - sumr[l - 1] - res.sumr);
				ret += (suma[r] - suma[l - 1] - res.suma);
			} else {
				c = min(lim, t - c);
				Info res = t2.query(rtp[r], 0, lim, 0, c) - t2.query(rtp[l - 1], 0, lim, 0, c);
				ret += res.sums;
				ret += 1ll * c * (sumr[r] - sumr[l - 1] - res.sumr);
			}
		}
		s.erase(itl, itr), s.insert(node(l, r, t));
		printf("%lld\n", ret);
	}
	return 0;
}

标签:Info,int,友谊,魔法,sumr,ret,lim,CF453E,suma
From: https://www.cnblogs.com/Custlo/p/17989647

相关文章

  • 魔法少女LJJ 题解
    魔法少女LJJ题解这题纯属就是迷惑题。。为什么这么说?注意数据范围:对100%的数据\(0\leqm\leq400000\),\(c\leq7\)。\(c\leq7\)!!这意味着根本没有删除操作。就连样例也是错的。Solution这题的各种操作,用并查集+线段树合并完成。如果你是被题目数据范围晃飞的,建议......
  • 计算机编程中的黑魔法编程是什么?如何求解一个浮点数的平方根倒数?计算机中的浮点数是如
    原视频:没有显卡的年代,这群程序员用4行代码优化游戏最原始的求解目标:(求一个浮点数的开方的导数)浮点数在计算机中的表示形式:对数的运算法则:A为a在计算机中的表示形式(二进制表示形式):求浮点数的平方根倒数的应用场景:这个情况,直白的说就......
  • 【Leetcode1949. 坚定的友谊】使用MySQL在无向图中寻找{"CompleteTripartite", {1, 1,
    目录题目地址思路代码MySQL代码逐行翻译为Pandas代码等效Cypher查询(未验证)题目地址https://leetcode.cn/problems/strong-friendship/思路就是在无向图中寻找这个pattern:(*Mathematica*)GraphData[{"CompleteTripartite",{1,1,3}}]SQL写还是比较麻烦。更加复杂的查询还是......
  • Java魔法值有哪些
    Java魔法值有哪些引言在Java编程中,我们经常会遇到一些被称为魔法值(MagicValue)的常量。这些常量通常以数字的形式出现在代码中,但其含义不太明确,使得代码可读性变差。本文将介绍Java魔法值的概念、常见的魔法值以及如何避免使用魔法值。什么是魔法值?魔法值指的是在代码中直接使......
  • Luogu P4924 [1007] 魔法少女小Scarlet
    [1007]魔法少女小Scarlet\(\color{cyan}link\)题目描述Scarlet最近学会了一个数组魔法,她会在\(n\timesn\)二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转\(90^\circ\)。首先,Scarlet会把\(1\)到\(n^2\)的正整数按照从左往右,从上至下的顺序填入初始的二维数组......
  • Docker 魔法解密:探索 UnionFS 与 OverlayFS
    本文主要介绍了Docker的另一个核心技术:UnionFileSystem。主要包括对overlayfs的演示,以及分析docker是如何借助ufs实现容器rootfs的。如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎关注微信公众号。搜索公众号【探索云原生】即可订阅1.概述......
  • 洛谷题单指南-模拟和高精度-P4924 [1007] 魔法少女小Scarlet
    原题链接:https://www.luogu.com.cn/problem/P4924题意解读:根据题意,通过模拟法,枚举每一个要旋转的矩阵,执行旋转操作即可,关键点在于如何进行矩阵旋转。设定矩阵inta[][],临时矩阵intt[][]用于保存旋转后的矩阵,矩阵长度为len。先考虑要旋转的区域左上角是a[0][0]的情况,区域内每......
  • 「暴力」拿出最少数目的魔法豆(力扣第2171题)
    本题为1月18日力扣每日一题题目来源:力扣第2171题题目tag:数位dp动态规划题面题目描述给定一个正整数数组beans,其中每个整数表示一个袋子里装的魔法豆的数目。请你从每个袋子中拿出一些豆子(也可以不拿出),使得剩下的非空袋子中(即至少还有一颗魔法豆的袋子)魔法豆的数目相等......
  • Docker 与 Linux Cgroups:资源隔离的魔法之旅
    这篇文章主要介绍了Docker如何利用Linux的ControlGroups(cgroups)实现容器的资源隔离和管理。最后通过简单Demo演示了如何使用Go和cgroups交互。如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎关注微信公众号。搜索公众号【探索云原生】即可订阅......
  • Python中的魔法方法
      Python中有很多魔法方法,它们以双下划线__开头和结尾,用于实现类的特殊行为。以下是一些常用的魔法方法:1.__init__(self,...)  初始化方法,用于创建对象并设置初始状态。2.__str__(self)  返回对象的非正式字符串表示形式,通过str()函数调用。3.__repr__(self)......