zoukankan      html  css  js  c++  java
  • ZOJ 1160

    线段树习题,利用了延迟标记,与普通线段树频发查询不同,这里只进行了一次查询,所以事实上只是利用了线段树的结构和延迟标记的思想

    几个注意点:

    • 要注意给出的n是线段涂色的次数,而非线段总长度,线段树的区间一直是[0, 8000]
    • 因为我是利用了map方便最终的计数,需要引入全局变量fom来记录上一个节点线段的颜色,同时还要注意访问到长度为一的线段时,要注意即使此时颜色为none,这是后也要修改全局变量,因为中间断开了的同颜色线段是算做两条线段,WA了好久的教训
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <map>
    using namespace std;
    
    const int maxn = 8e3+5;
    const int maxl = maxn<<2;
    const int none= -1;
    const int L= 0;
    const int R= 8000;
    
    typedef map<int, int> cRec;
    map<int, int> segCnt;
    int tree[maxl];
    int s, e, fom; // s, e represent colored segment
    
    inline int LeftChild(int i)
    {
    	return i<<1;
    }
    inline int RightChild(int i)
    {
    	return i<<1|1;
    }
    void Init()
    {
    	memset(tree, none, sizeof(tree));
    	segCnt.clear();
    	fom= none;
    }
    void PushDown(int rt, int l, int r)
    {
    	if (none== tree[rt] || l+1>= r){
    		return;
    	}
    	int lc= LeftChild(rt), rc= RightChild(rt), c= tree[rt];
    	tree[lc]= tree[rc]= c;
    	tree[rt]= none;
    }
    void Update(int rt, int l, int r, int c)
    {
    	if (l>= r){
    		return;
    	}
    	if (l>= s && r<= e){
    		tree[rt]= c;
    		return;
    	}
    
    	PushDown(rt, l, r);
    	int mid= (l+r)>>1;
    	if (s< mid){
    		Update(LeftChild(rt), l, mid, c);
    	}
    	if (mid< e){
    		Update(RightChild(rt), mid, r, c);
    	}
    }
    void Check(int rt, int l, int r)
    {
    	if (none!= tree[rt]){
    		if (fom!= tree[rt]){
    			fom= tree[rt];
    			++segCnt[fom];
    		}
    		return;
    	}
    	if (r== l+1){
    		fom= none;
    		return;
    	}
    	int mid= (l+r)>>1;
    	Check(LeftChild(rt), l, mid);
    	Check(RightChild(rt), mid, r);
    
    }
    inline void Ans()
    {
    	for (cRec::iterator iter= segCnt.begin(); segCnt.end()!= iter; ++iter){
    		printf("%d %d
    ", iter->first, iter->second);
    	}
    	putchar('
    ');
    }
    
    int main(int argc, char const *argv[])
    {
    	int n, c;
    	while (EOF!= scanf("%d", &n)){
    		Init();
    		while (n--){
    			scanf("%d %d %d", &s, &e, &c);
    			Update(1, L, R, c);
    		}
    		Check(1, L, R);
    		Ans();
    
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    《网络攻防与实践》第九周学习
    《网络攻防技术与实践》第八周作业
    《网络攻击技术与实践》第七周作业
    《网络攻防技术与实践》第六周学习
    《网络攻防技术与实践》第五周作业
    《网络攻防技术与实践》第四周学习
    《网络攻防技术与实践》第三周学习总结
    《网络攻防技术与实践》第二周学习总结
    20169214 2016-2017-2 《网络攻防实践》第十一周实验 SQL注入
    20169214 2016-2017-2 《移动平台开发实践》Android程序设计 实验报告
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/13397206.html
Copyright © 2011-2022 走看看