Poj2777(线段树+标记+状态压缩)
来源:互联网 发布:php 菜鸟教程 编辑:程序博客网 时间:2024/05/19 17:59
题目链接> http://poj.org/problem?id=2777
题目大意:给你一个长为L的板,然后给上边的每一段涂颜色, 给出一系列操作对应更新区间或输出该区间有多少中颜色, 本题肯定能想到线段树来解决,然后根据T<30想到用状态 压缩的方法,用位运算同时也要加上lazy标记,不然很容 易超时。
注意异或^的用法 x ^ (1 << (k - 1)) = 0 表示x的第k位(从 k = 1 开始)为1否则为0。
第一次写这方面的题,写的又长又丑,搞得我 挖了一发就不想再看自己写的代码了,而且本题 要注意所给的区间A到B可能A
#include <iostream>#include <sstream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <set>#include <vector>using namespace std;const int maxn = 100000 + 5;int flag;struct node { int lazy; int sum;};node tree[maxn*4];void build(int p, int l, int r){ if (l == r) { tree[p].sum = 1; tree[p].lazy = 1; return; } int mid = (l+r) >> 1; build(p<<1, l, mid); build(p<<1|1, mid+1, r); tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;}void push_down(int p, int l, int r, int z){ tree[p].lazy = 0;//这行不能丢,丢了就WA了 node &ll = tree[p<<1]; node &rr = tree[p<<1|1]; if ((ll.lazy^(1<<(z-1))) != 0) { ll.lazy = 1<<(z-1); ll.sum = ll.lazy; } if ((rr.lazy^(1<<(z-1))) != 0) { rr.lazy = 1<<(z-1); rr.sum = rr.lazy; }}void change(int p, int l, int r, int x, int y, int z){ int &s = tree[p].lazy; if (l >= x && r <= y) { if ((s^(1<<(z-1))) == 0) return; else { s = 1<<(z-1); tree[p].sum = s; } return; } for (int i = 0; i < 31; i++) { if ((s ^ (1<<i)) == 0) { push_down(p, l, r, i+1); break; } } int mid = (l+r)>>1; if (x <= mid) change(p<<1, l, mid, x, y, z); if (y > mid) change(p<<1|1, mid+1, r, x, y, z); tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum;}int query(int p, int l ,int r, int x, int y){ if (l >= x && r <= y) { return tree[p].sum; } for (int i = 0; i < 31; i++) { if ((tree[p].lazy ^ (1<<i)) == 0) { push_down(p, l, r, i+1); break; } } int mid = (l+r)>>1; int ans = 0; if (x <= mid) ans = ans|query(p<<1, l, mid, x, y); if (y > mid) ans = ans|query(p<<1|1, mid+1, r, x, y); tree[p].sum = tree[p<<1].sum|tree[p<<1|1].sum; return ans;}int main(){ //freopen("input.txt", "r", stdin); int L, T, op; cin >> L >> T >> op; memset(tree, 0, sizeof(tree)); build(1, 1, L);//建树 for (int i = 0; i < op; i++) { char ch; int x, y, z; scanf(" %c", &ch); if (ch == 'C') { scanf("%d%d%d", &x, &y, &z); if (x > y) swap(x, y); change(1, 1, L, x, y, z);//更新 } else { scanf("%d%d", &x, &y); if (x > y) swap(x, y); int tmp = query(1, 1, L, x, y);//询问 int ans = 0; for (int i = 0; i <= 30; i++) { if ((tmp&(1<<i)) ) ans++; } cout << ans << endl; } } return 0;}
0 0
- Poj2777(线段树+标记+状态压缩)
- poj2777线段树,状态压缩
- poj2777(线段树lazy标记的使用)
- poj2777-线段树应用(线段覆盖)
- poj2777 Count Color线段树延迟更新,二进制状态记录
- POJ2777(线段树区间更新+LAZY)
- POJ2777 Count Color(线段树)
- POJ2777(线段树)Count Color
- poj2777 色板游戏(线段树)
- POJ2777 Count Color(线段树+染色)
- poj2777 Count Color(线段树+状压)
- 线段树模板 poj2777
- POJ2777---线段树
- 线段树-POJ2777
- POJ2777(线段树)
- poj2777线段树
- poj2777 线段树
- poj2777(线段树)
- 双重DP实例2:K次购买股票的最大收益
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
- Android动态加载JAR包的实现方法
- 一、SDWebImage分析--库处理流程分析
- leetcode[108]:Convert Sorted Array to Binary Search Tree
- Poj2777(线段树+标记+状态压缩)
- JDBC URL中关于字符编码的配置参数
- HDUOJ Let the Balloon Rise 1004
- VIM常用操作
- [UnityShaderCookbook 读书笔记] [01] Unity Shader 基础
- 安卓与PC使用USB一种Socket通信方案
- Python向MySQL批量插入数据
- 判断中间目录是否存在
- Makefile经典教程(掌握这些足够)