P1558 色板游戏 [线段树 + 二进制状态压缩 + 懒标记区间重置]

P1558 色板游戏

时间限制: 1.00s 内存限制: 128.00MB

复制 Markdown

中文

退出 IDE 模式

题目背景

阿宝上学了,今天老师拿来了一块很长的涂色板。

题目描述

色板长度为 L,L 是一个正整数,所以我们可以均匀地将它划分成 L 块 1 厘米长的小方格。并从左到右标记为 1,2,...,L。

现在色板上只有一个颜色,老师告诉阿宝在色板上只能做两件事:

  1. C A B C 指在 A 到 B 号方格中涂上颜色 C。
  2. P A B 指老师的提问:A 到 B 号方格中有几种颜色。

学校的颜料盒中一共有 T 种颜料。为简便起见,我们把他们标记为 1,2,...,T。开始时色板上原有的颜色就为 1 号色。 面对如此复杂的问题,阿宝向你求助,你能帮助他吗?

输入格式

第一行有 3 个整数 L(1≤L≤105),T(1≤T≤30) 和 O(1≤O≤105)。 在这里 O 表示事件数。

接下来 O 行, 每行以 C A B CP A B 的形式表示所要做的事情(这里 A,B,C 为整数,可能 A>B,这样的话需要你交换 A 和 B)。

输出格式

对于老师的提问,做出相应的回答。每行一个整数。

输入输出样例

输入 #1复制运行

复制代码
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2

输出 #1复制运行

复制代码
2
1

说明/提示

【数据范围】

1≤L≤105,1≤T≤30,1≤O≤105。

1≤A,B≤L(不保证 A≤B),1≤C≤T。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N=1e5+5;
int a[N],n,m,t;
struct SegmentTree{
    int l,r,sum,upd;
    bool isupd;
    #define l(x) tree[x].l
    #define r(x) tree[x].r
    #define sum(x) tree[x].sum
    #define upd(x) tree[x].upd
    #define isupd(x) tree[x].isupd
}tree[N<<2];
void pushup(int p){
    sum(p)=sum(p<<1)|sum(p<<1|1);
}
void build(int p,int l,int r){
    l(p)=l,r(p)=r;
    if(l(p)==r(p)){
        sum(p)=1;return; 
    }
    int mid =(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}
void pushdown(int p){
    if(isupd(p)){
        upd(p<<1)=upd(p<<1|1)=upd(p);
        isupd(p<<1)=isupd(p<<1|1)=1;
        sum(p<<1)=sum(p<<1|1)=1<<(upd(p)-1);
        isupd(p)=0;
    }
}
void change(int p,int l,int r,int k){
    if(l<=l(p)&&r>=r(p)){
        upd(p)=k;
        sum(p)=1<<(upd(p)-1);
        isupd(p)=1;
        return;
    }
    pushdown(p);
    int mid=(l(p)+r(p))>>1;
    if(l<=mid)change(p<<1,l,r,k);
    if(r>mid)change(p<<1|1,l,r,k);
    pushup(p);
}
int query(int p,int l,int r){
    if(l<=l(p)&&r>=r(p)){return sum(p);}
    pushdown(p);
    int mid=(l(p)+r(p))>>1;
    int val=0;
    if(l<=mid)val|=query(p<<1,l,r);
    if(r>mid)val|=query(p<<1|1,l,r);
    return val;
}
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>t>>m;
    for(int i=1;i<=n;i++)a[i]=1;
    build(1,1,n);
    while(m--){
        int l,r;
        char op;
        cin>>op>>l>>r;
        if(l>r)swap(l,r);
        if(op=='C'){
            int k;cin>>k;
            change(1,l,r,k);
        }else {
            cout<<__builtin_popcountll(query(1,l,r))<<'\n';
        }
    }
    return 0;
}
相关推荐
DuHz13 分钟前
论文解读:用于数据分析的极值点对称模态分解方法 (Extreme-point Symmetric Mode Decomposition,ESMD)
论文阅读·算法·信息与通信·信号处理
HZZD_HZZD32 分钟前
用电负荷聚类分析实战:基于`scikit-learn`的`K-Means`与`DBSCAN`双算法对比、`PCA`降维可视化与智能电表负荷画像全流程
算法·scikit-learn·kmeans
MIngYaaa5201 小时前
2026暑期牛客多校1 2026-7-17
数据结构·算法
wabs6661 小时前
关于图论【卡码网107.寻找存在的路线的思考】
数据结构·算法·图论
半兽先生1 小时前
大模型技术开发与应用——4.大模型提示词工程实战
人工智能·算法
wuminyu1 小时前
JUC组件逐层剥离与深度剖析
java·linux·c语言·jvm·c++·算法
hhzz2 小时前
机器学习-算法模型系列文章:07-SVM 一巴掌拍出来的超平面:SVM核函数选错,再干净的数据也救不了你
算法·机器学习·支持向量机
geovindu2 小时前
java: Gale-Shapley Algorithm
java·开发语言·后端·算法
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-34 通讯录的录入与显示(C语言实现)
c语言·开发语言·数据结构·算法
zander2582 小时前
LeetCode 79. 单词搜索
算法·深度优先