线段树之状态压缩

本文探讨了线段树在处理区间信息时采用状态压缩的方法,包括将颜色转化为二进制存储并利用位运算,以及如何应用于色板游戏、XOR on Segment等题目。通过建立多棵线段树或使用DFS序将子树转化为区间来处理颜色上限较大的情况。
摘要由CSDN通过智能技术生成

线段树博大精深
对于线段树上的状态压缩, 个人的理解就是把修改的信息转化成二进制存储也不一定是二进制 , 再配上位运算, 来处理问题的一种方法

色板游戏
这一题应该是状态压缩的板子题, 将一段区间内的每个格子涂成某种颜色, 查询某段区间内颜色的种数.
方法1: 将颜色 c c c转化为 2 c 2^{c} 2c来存储, 这样二进制下的每一位1代表1种颜色, 修改的时候直接把这段区间的 d a t a data data修改为 2 c 2^{c} 2c, 延迟标记设为 c c c, 然后向下传递, 查询时只需要将答案转化为二进制, 然后查询二进制下1的个数即可
方法2: 由于颜色种类最多为30, 所以可以建30棵线段树, 每一颗线段树维护一种颜色, 查询时只需要查询每种颜色在这段区间内存不存在即可

XOR on Segment
给你一个n个数的数列, 两种操作, 求出给定区间内数的和, 或者将给定区间内的每个数异或上 x x x.
方法: 建20棵线段树, 每一颗维护二进制下每一位的1的个数.修改时, 根据异或规则修改. 查询时, 查询每一位的1的个数
a n s = ∑ i = 0 20 2 i ∗ q u e r y ans=\displaystyle\sum_{i=0}^{20}2^i*query ans=i=0202iquery

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
#define x first
#define y second
const int MAX_N = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
//
//
#define int ll
int n, m;
int a[MAX_N], d[21];
struct SegTree {
   
    int l, r;
    int dat, lazy;
} tree[21][MAX_N];
inline void push_up(int id, int x) {
   
    tree[id][x].dat = tree[id][x * 2].dat + tree[id][x * 2 + 1].dat;
}
inline void push_down(int id, int x, int ln, int rn) {
   
    if(tree[id][x].lazy) {
   
        tree[id][x * 2].dat = ln - tree
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值