敲了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. java_test_week4

    20165310 week4 JDK知识点 启动JDK: javac -g <java>:参数一定要加上-g jdk -classpath .:./bin <class>:一开 ...

  2. 20162311 解读同伴的收获&解决同伴的问题(11月29日,周三)

    20162311 解读同伴的收获&解决同伴的问题(11月29日,周三) 解读同伴的收获 我的同组同学是20162325学号金立清同学 同组同学的收获是:递归算法的非递归实现.分治法.动态规划法 ...

  3. LM2596、LM2576

    找来的资料,参考一下,震荡频率不一样,最大输入电压不一样. LM2576系列是的3A电流输出降压开关型集成稳压电路, ●最大输出电流:3A; ●振荡频率:52kHz; ●转换效率:75%-88%(不同 ...

  4. python字符串格式化之format

    用法: 它通过{}和:来代替传统%方式 1.使用位置参数 要点:从以下例子可以看出位置参数不受顺序约束,且可以为{},只要format里有相对应的参数值即可,参数索引从0开,传入位置参数列表可用*列表 ...

  5. Python3基础 yield 在函数中的用法示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  6. Python3基础 str 循环输出list中每个单词及其长度

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  7. Sql 最简单的Sqlserver连接

    string name = txtUserName.Text.Trim();//移除用户名前部和后部的空格 string pwd = txtUserPwd.Text.Trim();//移除密码前部和后 ...

  8. Facebook广告API系列 2 - Audience Management

    Facebook广告API系列 2 Facebook marketing API有三大组成部分: Audience Management Ads Management Ads Insights 本篇稍 ...

  9. 【转】Makefile 中:= ?= += =的区别

    最近接触使用C++项目,需要使用Makefile,因此需要好好学习下. [转自]:http://www.cnblogs.com/wanqieddy/archive/2011/09/21/2184257 ...

  10. MVC ---- EF三层代码

    1.DAL层 using Night.Models; using System; using System.Collections.Generic; using System.Data.Entity. ...