敲了n遍....RE愉快的debug了一晚上...发现把#define maxn = 100000 + 10 改成 #define maxn = 100010 就过了....感受一下我呵呵哒的表情....

貌似这个题用了很经典的线段树和位运算。懂了。但不是很懂。确实觉得用的很巧妙。只想说。好坑。

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N = 100010 struct Tree{
int l,r;
int col; // 用一个32位的int型,每一位对应一种颜色,用位运算代替bool col[32]
bool cover; // 表示这个区间都被涂上同一种颜色,线段树效率的体现,否则插入就是0(n)了。
}tree[N<<]; void PushUp(int rt){ // 最后递归回来再更改父节点的颜色
tree[rt].col=tree[L(rt)].col | tree[R(rt)].col;
} void build(int l, int r, int root) {
tree[root].l = l;
tree[root].r = r;
tree[root].col = ;
tree[root].cover = ; if (l == r) return;
int mid = (l+r)/;
build(l, mid, *root);
build(mid+, r, *root+);
} void PushDown(int root) { // 把标记向下传递
tree[*root].col = tree[root].col;
tree[*root].cover = ;
tree[*root+].col = tree[root].col;
tree[*root+].cover = ;
tree[root].cover = ; // 懂了。
}
void update(int val, int l, int r, int root) { // 更新某个区间的颜色
if (l <= tree[root].l && tree[root].r <= r) {
tree[root].col = val; // 说明这个区间只包含一种颜色了。而且是val. 所以修改完成、get it!!!
tree[root].cover = ;
return ;
} if (tree[root].col == val) return; // 说明当前的区间内的颜色已经只有这一种了。所以没必要再往下、??剪枝
if (tree[root].cover) PushDown(root); // 因为下面可能要修改这个区间的某个子区间的颜色了。
// 否则就不断的向下分解区间
int mid = (tree[root].l+tree[root].r)/;
if (r <= mid) update(val, l, r, *root);
else if (l >= mid+) update(val, l, r, *root+);
else {
update(val, l, mid, *root);
update(val, mid+, r, *root+);
}
PushUp(root); // 递归修改完孩子节点的颜色后 修改父亲节点的颜色
} int sum; void query(int L,int R,int rt){
if(L<=tree[rt].l && R>=tree[rt].r){
sum |= tree[rt].col;
return ;
}
if(tree[rt].cover){ // 这个区间全部为1种颜色,就没有继续分割区间的必要了
sum |= tree[rt].col; // 颜色种类相加的位运算代码
return;
}
int mid=(tree[rt].l+tree[rt].r)>>;
if(R<=mid)
query(L,R,L(rt));
else if(L>=mid+)
query(L,R,R(rt));
else{
query(L,mid,L(rt));
query(mid+,R,R(rt));
}
} int solve(){
int ans=;
while(sum){
if(sum&)
ans++;
sum>>=;
}
return ans;
} void swap(int &a, int &b) {
int t = a;
a = b;
b = t;
} int main() {
int l, n, m;
while(~scanf("%d%d%d", &l, &n, &m)) {
build(, l, );
char op[];
int a, b, c; for (int i=; i<m; ++i) {
scanf("%s", op);
if (op[] == 'C') {
scanf("%d%d%d", &a, &b, &c);
if (a > b) swap(a, b);
update(<<(c-), a, b, );
}
else if (op[] == 'P') {
scanf("%d%d", &a, &b);
if (a > b) swap(a, b);
sum = ;
query(a, b, );
printf("%d\n",solve());
}
}
}
return ;
}

poj 2777线段树应用的更多相关文章

  1. poj 2777(线段树+lazy思想) 小小粉刷匠

    http://poj.org/problem?id=2777 题目大意 涂颜色,输入长度,颜色总数,涂颜色次数,初始颜色都为1,然后当输入为C的时候将x到y涂为颜色z,输入为Q的时候输出x到y的颜色总 ...

  2. POJ 2777——线段树Lazy的重要性

    POJ 2777 Count Color --线段树Lazy的重要性 原题 链接:http://poj.org/problem?id=2777 Count Color Time Limit: 1000 ...

  3. POJ 2777(线段树)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42507   Accepted: 12856 Des ...

  4. POJ 2777 线段树基础题

    题意: 给你一个长度为N的线段数,一开始每个树的颜色都是1,然后有2个操作. 第一个操作,将区间[a , b ]的颜色换成c. 第二个操作,输出区间[a , b ]不同颜色的总数. 直接线段树搞之.不 ...

  5. Count Color POJ - 2777 线段树

    Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...

  6. poj 2777 线段树的区间更新

    Count Color Time Limit: 1000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...

  7. poj 2777 线段树 区间更新+位运算

    题意:有一个长板子,分成多段,有两种操作,第一种是C给从a到b那段染一种颜色c,另一种是P询问a到b有多少种不同的颜色.Sample Input2 2 4  板长 颜色数目 询问数目C 1 1 2P ...

  8. poj 2886 线段树+反素数

    Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12744   Acc ...

  9. poj 3468(线段树)

    http://poj.org/problem?id=3468 题意:给n个数字,从A1 …………An m次命令,Q是查询,查询a到b的区间和,c是更新,从a到b每个值都增加x.思路:这是一个很明显的线 ...

随机推荐

  1. 20145127《java程序设计》第五周学习总结

    教材学习内容总结 第八章 异常处理 1.try catch java中所有错误会被打包成对象,可以进行尝试捕捉代表错误的对象进行处理. Import java.until.Scanner; Publi ...

  2. STM32.定时器

    一.定时器分类 11个定时器: 定时器: 1.8  高级(7路PWM输出) 2.3.4.5 通用(4路) 6.7    基本 2个看门狗 1个sysTick 时钟分布: 二.这里我们主要对定时器中 定 ...

  3. VC++开机自动启动程序的几种方法 (转载)

    转载:http://blog.csdn.net/zhazhiqiang/article/details/51909703 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能 ...

  4. win32 自定义右键菜单

    /**************************************************************************** 几大主要问题: 1.通过处理WM_MOUSE ...

  5. 史丰收速算|2014年蓝桥杯B组题解析第四题-fishers

    史丰收速算 史丰收速算法的革命性贡献是:从高位算起,预测进位.不需要九九表,彻底颠覆了传统手算! 速算的核心基础是:1位数乘以多位数的乘法. 其中,乘以7是最复杂的,就以它为例. 因为,1/7 是个循 ...

  6. 伪类:after的使用以及结合attr来添加属性的技巧

    本案例以实现侧边栏的效果为例来说明 直接上代码看效果: css <style type="text/css"> *{;;list-style: none;} ul{;t ...

  7. 【Android实验】线程的使用-计时器

    目录 实验目的 实验要求 实验过程 实验结果 实验代码 实验总结 实验目的 熟悉和掌握Android线程的使用 实验要求 完成一个秒表,具备启停功能,正确使用工作线程完成界面刷新 分析秒表的计时是否准 ...

  8. NS-3 MyFirstScriptExample

    安装好了NS-3之后,我根据一些教程学习了NS-3的几个关键的概念,然后照着例子和自己对它的一些理解,尝试的打了我自己的第一个脚本程序:MyFirstScriptExample 具体代码如下: #in ...

  9. HDU 2544 最短路(Dijkstra)

    https://vjudge.net/problem/HDU-2544 题意: 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<=10000),N表示成都的大街上有几个 ...

  10. HTTP 随笔

    浏览器发送HTTP请求主要分为三部分请求行,Response Headers(响应头信息)和Request Headers(请求头信息). 请求行有分为三部分:请求方法,请求路径和请求协议 请求方法有 ...