首页 > 其他分享 >CodeForces 1423G Growing flowers

CodeForces 1423G Growing flowers

时间:2023-02-07 08:11:05浏览次数:70  
标签:node insert ss ll st 1423G add Growing flowers

洛谷传送门

CF 传送门

先离散化颜色。考虑对每种颜色单独求出答案。对于颜色 \(x\),可以用总方案数 \(n-k+1\) 减去一个 \(x\) 都不包含的区间数量。对于这个,假设相邻两个颜色 \(x\) 的下标分别为 \(l,r\),那么中间那段极长不含 \(x\) 的区间对答案的贡献就是 \(\max(0,r-l-k)\)。

看到区间推平,考虑 ODT 维护,区间推平可转化为若干加入或删除极长不含某种颜色的连续段的操作。对于一个固定的 \(l,r\),它对答案的贡献是一个等差数列的形式,即对 \(k=1\) 有 \(-(r-l-1)\) 贡献,对 \(k=2\) 有 \(-(r-l-2)\) 贡献,以此类推。用线段树维护,询问直接在线段树上查即可。

时间复杂度 \(O((n+q) \log n)\),带个 set 的常数。

code
// Problem: G. Growing flowers
// Contest: Codeforces - Bubble Cup 13 - Finals [Online Mirror, unrated, Div. 1]
// URL: https://codeforces.com/problemset/problem/1423/G
// Memory Limit: 256 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

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

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

const int maxn = 200100;

ll n, m, a[maxn];

namespace SGT {
	ll tree[maxn << 2], tag[maxn << 2];
	
	void pushup(int x) {
		tree[x] = tree[x << 1] + tree[x << 1 | 1];
	}
	
	void pushdown(int x, int l, int r) {
		if (!tag[x]) {
			return;
		}
		int mid = (l + r) >> 1;
		tree[x << 1] += tag[x] * (mid - l + 1);
		tree[x << 1 | 1] += tag[x] * (r - mid);
		tag[x << 1] += tag[x];
		tag[x << 1 | 1] += tag[x];
		tag[x] = 0;
	}
	
	void update(int rt, int l, int r, int ql, int qr, ll x) {
		if (ql <= l && r <= qr) {
			tree[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 tree[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;
	}
}

struct node {
	ll l, r, x;
	node(ll a = 0, ll b = 0, ll c = 0) : l(a), r(b), x(c) {}
};
set<node> st, ss[maxn];

bool operator < (node a, node b) {
	return a.l < b.l;
}

struct que {
	ll op, x, y, z;
} qq[maxn];

ll lsh[maxn], tot;

void add(ll x, ll y) {
	if (x < 1) {
		return;
	}
	SGT::update(1, 1, n, 1, 1, x * y);
	SGT::update(1, 1, n, 2, min(n, x + 1), -y);
}

auto split(ll pos) {
	auto it = st.lower_bound(node(pos));
	if (it != st.end() && it->l == pos) {
		return it;
	}
	--it;
	node u = *it;
	st.erase(it);
	ss[u.x].erase(u);
	ss[u.x].insert(node(u.l, pos - 1, u.x));
	ss[u.x].insert(node(pos, u.r, u.x));
	st.insert(node(u.l, pos - 1, u.x));
	return st.insert(node(pos, u.r, u.x)).fst;
}

void insert(node u) {
	ll l = (--ss[u.x].lower_bound(u))->r;
	ll r = ss[u.x].upper_bound(u)->l;
	add(r - l - 1, -1);
	add(u.l - l - 1, 1);
	add(r - u.r - 1, 1);
	ss[u.x].insert(u);
}

void del(node u) {
	ll l = (--ss[u.x].lower_bound(u))->r;
	ll r = ss[u.x].upper_bound(u)->l;
	add(r - l - 1, 1);
	add(u.l - l - 1, -1);
	add(r - u.r - 1, -1);
	ss[u.x].erase(u);
}

void assign(ll l, ll r, ll x) {
	auto itr = split(r + 1), itl = split(l);
	for (auto it = itl; it != itr; ++it) {
		del(*it);
	}
	st.erase(itl, itr);
	st.insert(node(l, r, x));
	insert(node(l, r, x));
}

int main() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		lsh[++tot] = a[i];
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%lld%lld", &qq[i].op, &qq[i].x);
		if (qq[i].op == 1) {
			scanf("%lld%lld", &qq[i].y, &qq[i].z);
			lsh[++tot] = qq[i].z;
		}
	}
	sort(lsh + 1, lsh + tot + 1);
	tot = unique(lsh + 1, lsh + tot + 1) - lsh - 1;
	for (int i = 1; i <= tot; ++i) {
		ss[i].insert(node(0, 0, i));
		ss[i].insert(node(n + 1, n + 1, i));
		add(n, 1);
	}
	st.insert(node(0, 0));
	st.insert(node(n + 1, n + 1));
	for (int i = 1; i <= n; ++i) {
		a[i] = lower_bound(lsh + 1, lsh + tot + 1, a[i]) - lsh;
		insert(node(i, i, a[i]));
		st.insert(node(i, i, a[i]));
	}
	for (int i = 1; i <= m; ++i) {
		if (qq[i].op == 1) {
			qq[i].z = lower_bound(lsh + 1, lsh + tot + 1, qq[i].z) - lsh;
		}
		int op = qq[i].op;
		if (op == 1) {
			ll l = qq[i].x, r = qq[i].y, x = qq[i].z;
			assign(l, r, x);
		} else {
			ll x = qq[i].x;
			printf("%lld\n", tot * (n - x + 1) - SGT::query(1, 1, n, 1, x));
		}
	}
	return 0;
}

标签:node,insert,ss,ll,st,1423G,add,Growing,flowers
From: https://www.cnblogs.com/zltzlt-blog/p/17097187.html

相关文章

  • GrowingIO配置-UTM
    一、什么是UTM参数UTM:UrchinTrackingModule(UTM)parameters。Urchin是以网页模式为管理接口的主机纪录文件分析工具,能够使用浏览器来观看统计资料。UTM是一套标准的......
  • CF451E Devu and Flowers
    \(CF451E\)\(Devu\)\(and\)\(Flowers\)链接:https://www.luogu.com.cn/problem/CF451E题目描述:将一些球丢进一个盒子里,每一个求有一种颜色,有多少种本质不同的方法......
  • CF451E Devu and Flowers
    $CF451E$$Devu$$and$$Flowers$链接:https://www.luogu.com.cn/problem/CF451E题目描述:将一些球丢进一个盒子里,每一个求有一种颜色,有多少种本质不同的方法题解:......
  • [dp 记录]agc024E Sequence Growing Hard
    题意:给定一个序列,每次往其中插入\([1,k]\)间的一数,要求字典序递增,求方案数。设插入\(i\)数的数列为\(A_i\),存在一个\(A_i\)不同即两插入方案不同,否则即一致。\(n......
  • 基于ResNet的花卉图片分类 —— tensorflow版(flowers image classification based on
    最近看了《TensorFlow深度学习实战(微课视频版)》——清华大学出版社一书中的11章节《基于ResNet的花卉图片分类》,觉得写的不错,是个关于ResNet的好例子,所以整理下,分享给......
  • Compacting, Picking and Growing for Unforgetting Continual Learning论文阅读笔记
    摘要本文提出了一种简单有效的连续学习策略,利用了深度模型压缩、关键权重选择和渐进网络扩展的原则并进行整合。方法的优点:避免遗忘、允许模型扩展,同时可以通过之前的积......
  • 【luogu SP7685】FLWRS - Flowers(DP)(容斥)
    FLWRS-Flowers题目链接:luoguSP7685题目大意给你模数m,问你有多少个长度为n的排列满足相邻两个差不为1。思路首先一个简单的想法是容斥。那有\(n\)对相邻的不......