zoukankan      html  css  js  c++  java
  • [Luogu] P1558 色板游戏

    (Link)

    Description

    给定一个长为(n)的区间,(m)次操作,给子区间涂一种颜色,或者查询一个区间内有多少种颜色。颜色种类数(le30),初始颜色为(1)(n,mle10^5)

    Solution

    开始想的是开(30)棵线段树,或者每个区间开一个(vector)存颜色,但后来才发现其实完全没必要。注意到颜色种类数很少,所以其实可以把它压成一个状态(S),其中(S)从左往右数第(i)位是(1)表示这个区间内有(i)这种颜色。

    那么这就很好维护了。(pushdown)就直接覆盖,(pushup)就是对儿子进行或运算就好了。

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ls(x) (x << 1)
    #define rs(x) (x << 1 | 1)
    
    int n, m, mx;
    
    struct node
    {
    	int l, r, col, tag;
    }t[400005];
    
    char ch[2];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    void push_up(int p)
    {
    	t[p].col = (t[ls(p)].col | t[rs(p)].col);
    	return;
    }
    
    void push_down(int p)
    {
    	if (!t[p].tag) return;
    	t[ls(p)].tag = t[p].tag;
    	t[rs(p)].tag = t[p].tag;
    	t[ls(p)].col = (1 << (t[p].tag - 1));
    	t[rs(p)].col = (1 << (t[p].tag - 1));
    	t[p].tag = 0;
    	return;
    }
    
    void build(int p, int l0, int r0)
    {
    	t[p].l = l0; t[p].r = r0;
    	if (l0 == r0)
    	{
    		t[p].col = 1;
    		return;
    	}
    	int mid = (t[p].l + t[p].r) >> 1;
    	build(ls(p), l0, mid);
    	build(rs(p), mid + 1, r0);
    	push_up(p);
    	return;
    }
    
    void update(int p, int l0, int r0, int d)
    {
    	if (l0 <= t[p].l && t[p].r <= r0)
    	{
    		t[p].col = (1 << (d - 1));
    		t[p].tag = d;
    		return;
    	}
    	push_down(p);
    	int mid = (t[p].l + t[p].r) >> 1;
    	if (l0 <= mid) update(ls(p), l0, r0, d);
    	if (r0 > mid) update(rs(p), l0, r0, d);
    	push_up(p);
    	return;
    }
    
    int query(int p, int l0, int r0)
    {
    	if (l0 <= t[p].l && t[p].r <= r0) return t[p].col;
    	push_down(p);
    	int mid = (t[p].l + t[p].r) >> 1, now = 0;
    	if (l0 <= mid) now = now | query(ls(p), l0, r0);
    	if (r0 > mid) now = now | query(rs(p), l0, r0);
    	return now;
    }
    
    int main()
    {
    	n = read(); mx = read(); m = read();
    	build(1, 1, n);
    	while (m -- )
    	{
    		scanf("%s", ch);
    		if (ch[0] == 'C')
    		{
    			int l0 = read(), r0 = read(), c = read();
    			if (l0 > r0) swap(l0, r0);
    			update(1, l0, r0, c);
    		}
    		else
    		{
    			int l0 = read(), r0 = read();
    			if (l0 > r0) swap(l0, r0);
    			int cnt = query(1, l0, r0), res = 0;
    			for (int i = 0; i <= mx - 1; i ++ )
    				if (cnt & (1 << i))
    					res ++ ;
    			printf("%d
    ", res);
    		}	
    	}
    	return 0;
    }
    
  • 相关阅读:
    安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
    各种编程语言的深度学习库整理
    十个开源深度学习框架
    深度学习框架的评估与比较
    Caffe 深度学习框架上手教程
    机器视觉开源代码集合
    人工智能的妙用:谷歌公布图像字幕技术
    谷歌推出最新图像识别工具Google Cloud Vision API
    机器学习常见算法分类汇总
    神经网络的分类及其应用
  • 原文地址:https://www.cnblogs.com/andysj/p/14006233.html
Copyright © 2011-2022 走看看