首页 > 其他分享 >CodeForces 1924B Space Harbour

CodeForces 1924B Space Harbour

时间:2024-01-28 11:11:44浏览次数:22  
标签:typedef Space ll CodeForces Harbour update fst long ql

洛谷传送门

CF 传送门

不知道为什么好像大家在这题上花了挺久的。

发现对于一对相邻的港口 \((x_i, x_{i + 1})\),\(x \in (x_i, x_{i + 1})\) 的花费是 \(y_i (x_{i + 1} - x)\)。拆开得 \(y_i x_{i + 1} - y_i x\)。

考虑用 set 维护所有港口,这样可以知道一个港口左边和右边的港口的坐标和价值。那么前一项 \(y_i x_{i + 1}\) 可以线段树区间覆盖,后一项 \(-y_i x\) 也可以线段树区间覆盖处理,相当于让一个代表 \([l, r]\) 区间的线段树结点的和加上 \(- y_i \frac{(l + r)(r - l + 1)}{2}\)。这个标记是可以下传的。

总时间复杂度为 \(O((m + q) \log n)\)。

code
// Problem: B. Space Harbour
// Contest: Codeforces - Codeforces Round 921 (Div. 1)
// URL: https://codeforces.com/contest/1924/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 300100;

ll n, m, q, a[maxn], b[maxn];

inline ll calc(ll l, ll r) {
	return (l + r) * (r - l + 1) / 2;
}

struct {
	ll a[maxn << 2], tag[maxn << 2];
	
	inline void pushup(int x) {
		a[x] = a[x << 1] + a[x << 1 | 1];
	}
	
	inline void init() {
		mems(tag, -1);
	}
	
	inline void pushdown(int x, int l, int r) {
		if (tag[x] == -1) {
			return;
		}
		int mid = (l + r) >> 1;
		a[x << 1] = tag[x] * (mid - l + 1);
		a[x << 1 | 1] = tag[x] * (r - mid);
		tag[x << 1] = tag[x << 1 | 1] = tag[x];
		tag[x] = -1;
	}
	
	void update(int rt, int l, int r, int ql, int qr, ll x) {
		if (ql > qr) {
			return;
		}
		if (ql <= l && r <= qr) {
			a[rt] = x * (r - l + 1);
			tag[rt] = x;
			return;
		}
		pushdown(rt, l, r);
		int mid = (l + r) >> 1;
		if (ql <= mid) {
			update(rt << 1, l, mid, ql, qr, x);
		}
		if (qr > mid) {
			update(rt << 1 | 1, mid + 1, r, ql, qr, x);
		}
		pushup(rt);
	}
	
	ll query(int rt, int l, int r, int ql, int qr) {
		if (ql <= l && r <= qr) {
			return a[rt];
		}
		pushdown(rt, l, r);
		int mid = (l + r) >> 1;
		ll res = 0;
		if (ql <= mid) {
			res += query(rt << 1, l, mid, ql, qr);
		}
		if (qr > mid) {
			res += query(rt << 1 | 1, mid + 1, r, ql, qr);
		}
		return res;
	}
} t1;

struct {
	ll a[maxn << 2], tag[maxn << 2];
	
	inline void pushup(int x) {
		a[x] = a[x << 1] + a[x << 1 | 1];
	}
	
	inline void init() {
		mems(tag, -1);
	}
	
	inline void pushdown(int x, int l, int r) {
		if (tag[x] == -1) {
			return;
		}
		int mid = (l + r) >> 1;
		a[x << 1] = tag[x] * calc(l, mid);
		a[x << 1 | 1] = tag[x] * calc(mid + 1, r);
		tag[x << 1] = tag[x << 1 | 1] = tag[x];
		tag[x] = -1;
	}
	
	void update(int rt, int l, int r, int ql, int qr, ll x) {
		if (ql > qr) {
			return;
		}
		if (ql <= l && r <= qr) {
			a[rt] = x * calc(l, r);
			tag[rt] = x;
			return;
		}
		pushdown(rt, l, r);
		int mid = (l + r) >> 1;
		if (ql <= mid) {
			update(rt << 1, l, mid, ql, qr, x);
		}
		if (qr > mid) {
			update(rt << 1 | 1, mid + 1, r, ql, qr, x);
		}
		pushup(rt);
	}
	
	ll query(int rt, int l, int r, int ql, int qr) {
		if (ql <= l && r <= qr) {
			return a[rt];
		}
		pushdown(rt, l, r);
		int mid = (l + r) >> 1;
		ll res = 0;
		if (ql <= mid) {
			res += query(rt << 1, l, mid, ql, qr);
		}
		if (qr > mid) {
			res += query(rt << 1 | 1, mid + 1, r, ql, qr);
		}
		return res;
	}
} t2;

set<pii> S;

inline void upd(ll x, ll y, ll z) {
	t1.update(1, 1, n, x + 1, y - 1, z * y);
	t2.update(1, 1, n, x + 1, y - 1, -z);
}

void solve() {
	t1.init();
	t2.init();
	scanf("%lld%lld%lld", &n, &m, &q);
	for (int i = 1; i <= m; ++i) {
		scanf("%lld", &a[i]);
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%lld", &b[i]);
		S.emplace(a[i], b[i]);
	}
	for (auto it = S.begin(); next(it) != S.end(); ++it) {
		auto jt = next(it);
		upd(it->fst, jt->fst, it->scd);
	}
	while (q--) {
		ll op, x, y;
		scanf("%lld%lld%lld", &op, &x, &y);
		if (op == 1) {
			S.emplace(x, y);
			t1.update(1, 1, n, x, x, 0);
			t2.update(1, 1, n, x, x, 0);
			auto it = S.find(mkp(x, y));
			auto p = prev(it), q = next(it);
			upd(p->fst, it->fst, p->scd);
			upd(it->fst, q->fst, it->scd);
		} else {
			printf("%lld\n", t1.query(1, 1, n, x, y) + t2.query(1, 1, n, x, y));
		}
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,Space,ll,CodeForces,Harbour,update,fst,long,ql
From: https://www.cnblogs.com/zltzlt-blog/p/17992576

相关文章

  • CodeForces 1924D Balanced Subsequences
    洛谷传送门CF传送门发现去掉匹配的\(2k\)个括号后,剩下的串一定形如\())\ldots)((\ldots(\),其中右括号数量为\(a=m-k\),左括号数量为\(b=n-k\)。考虑把剩下的串像\())\ldots)\mid((\ldots(\)一样分成两半。枚举左半边加入了\(\frac{i}{2}\)对匹配,则......
  • hey_left 18 Codeforces Round 920 (Div. 3)
    题目链接A.根据正方形4个角的特性,可以把它们排序处理,得到长和高,相乘得面积#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;boolcmp(pair<int,int>x,pair<int,int>y){if(x.first==y.first)returnx.second<y.second;e......
  • Codeforces Educational Round
    CodeforcesEducationalRoundEducationalCodeforcesRound160(RatedforDiv.2)(A-D)https://www.cnblogs.com/ComistryMo/articles/17920495.htmlEducationalCodeforcesRound161(RatedforDiv.2)(A-E)https://www.cnblogs.com/ComistryMo/articles/17983580......
  • Educational Codeforces Round 65 (Rated for Div. 2)C. News Distribution(模拟,计算的
    这道题目明显和出现4次的数和出现2次的数的个数有关系,只需要在每次更新之后维护这两个信息即可,我们在算出现2次的数的个数时其实会把出现4次的数的个数会把出现2次的数的个数+2,在判断时需要考虑这一点。也就是\(cnt2>=4\&\&cnt4>=1\)时才有解#include<bits/stdc++.h>#definer......
  • CodeForces 995F Cowmpany Cowmpensation
    洛谷传送门CF传送门考虑一个显然的树形dp,设\(f_{u,i}\)为\(u\)结点染颜色\(i\)的方案数,有\(f_{u,i}=\prod\limits_{v\inson_u}\sum\limits_{j=1}^if_{v,j}\)。前缀和后可得\(f_{u,i}=f_{u,i-1}+\prod\limits_{v\inson_u}f_{v,i}\)。发现\(f_......
  • Codeforces Round 912 (Div
    AHalloumiBoxes题目大意给定一个数组A,我们可以对数组惊醒多次操作,操作如下:我们可以将数组中的某一段倒置,但是长度不能超过K,例如:反转子数组意味着选择两个索引i和j(其中1<=i<=j<=n)并将数组\[a_1,a_2,…,a_n\]改为\[a_1,a_2,…,a_{i−1},a_{j},a_{j−1},…......
  • Codeforces Round 913 (Div
    ARook题目大意给一个国际象棋棋盘,有t次询问,每次询问给定一个棋子坐标s例如d4.问:输出这个棋子上下左右四个方向的坐标解题思路两个for循环暴力求解代码#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'constintINF=0x3f3f3f3f;voidso......
  • Codeforces Round 914 (Div
    AForked!题目大意给定王后和国王的位置,马可以先朝一个方向走a步,再朝另一个方向走b步问:马有多少个位置可以同时走到皇后和国王解题思路就无脑遍历一下马能走到国王和皇后的位置然后再判断下有没有相同的位置代码#include<bits/stdc++.h>#defineintlonglong......
  • Codeforces Round 916 (Div
    AProblemsolvingLog题目描述给一个整数n,字符串s,字符串中s[i]表示第i分钟解决第s[i]题.问题A需要1分钟解决,问题B需要2分钟解决,以此类推.问:可以解决多少题?解题思路遍历字符串,统计问题A--Z用了多少时间解决.最后在遍历数组,判断问题A--Z是否满足解决时间.代......
  • Educational Codeforces Round 159 (Rated for Div
    EducationalCodeforcesRound159(RatedforDiv.2)ABinaryImbalance题目大意给定一个长度为n的一个01字符串,我们执行以下操作:当s[i]!=s[i+1]在中间插入0问:是否可以实现0的个数大于1的个数解题思路由题意可以明显看出只要有0就可以实现。下面简单分析下:0的个数大......