【2022年10月27日A组】生日【线段树】

48 篇文章 0 订阅
24 篇文章 0 订阅

在这里插入图片描述

思路:

直接开权值线段树维护就好了

c o d e code code

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int MAXN = 1e5 + 2;

int n, m, K;
struct node {
	bool v[31];
	int flag;
}tr[MAXN << 2];
int g[31];

inline void down(register int k, register int l, register int r) {
	register int mid = l + r >> 1, left = (k << 1), right = (k << 1 | 1);
	tr[left].flag = tr[right].flag = tr[k].flag;
	memset(tr[left].v, 0, sizeof(tr[left].v));
	memset(tr[right].v, 0, sizeof(tr[right].v));
	tr[left].v[tr[k].flag] = tr[right].v[tr[k].flag] = 1;
	tr[k].flag = 0;
}

inline void mix_(register int k) {
	register int left = (k << 1), right = (k << 1 | 1);
	for(register int i = 1; i <= K; i ++) tr[k].v[i] = tr[left].v[i] | tr[right].v[i];
}

inline void build(register int k, register int l, register int r) {
	if(l > r) return ;
	tr[k].v[1] = 1;
	register int mid = l + r >> 1;
	if(l == r) return ;
	build(k << 1, l, mid);
	build(k << 1 | 1, mid + 1, r);
}

inline void change(register int k, register int l, register int r, register int x, register int y, register int z) {
	if(x <= l && r <= y) {
		memset(tr[k].v, 0, sizeof(tr[k].v));
		tr[k].v[z] = 1;
		tr[k].flag = z;
		return ;
	}
	if(tr[k].flag != 0) down(k, l, r);
	register int mid = l + r >> 1;
	if(x <= mid) change(k << 1, l, mid, x, y, z);
	if(y > mid) change(k << 1 | 1, mid + 1, r, x, y, z);
	mix_(k);
}

inline void query_(register int k, register int l, register int r, register int x, register int y) {
	if(x <= l && r <= y) {
		for(register int i = 1; i <= K; i ++) g[i] |= tr[k].v[i];
		return ;
	}
	if(tr[k].flag != 0) down(k, l, r);
	register int mid = l + r >> 1;
	if(x <= mid) query_(k << 1, l, mid, x, y);
	if(y > mid) query_(k << 1 | 1, mid + 1, r, x, y);
	mix_(k);
}

int main() {
	scanf("%d%d%d", &n, &m, &K);
	build(1, 1, n);
	for(register int i = 1; i <= m; i ++) {
		string s;
		register int l, r, x;
		cin>>s;
		scanf("%d%d", &l, &r);
		if(s == "C") {
			scanf("%d", &x);
			change(1, 1, n, l, r, x);
		}
		else {
			memset(g, 0, sizeof(g));
			query_(1, 1, n, l, r);
			register int sum = 0;
			for(register int i = 1; i <= K; i ++) if(g[i]) sum ++;
			printf("%d\n", sum);
		}
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值