您的位置:首页 > 其它

线段树成段更新 zoj 1610

2014-07-03 22:41 309 查看
2014/7/3

我是彩笔系列

CE主力

线段树很可怕,从前学过,和树状数组一起学的...果断抛弃了它...后来发现某些情况线段树更加合适(树状数组空间想象能力有点捉计)。现在再来做...完全忘记了ORZ

类似于线段树这种数据结构有三种方法可以写:数组模拟,结构体,指针。指针果断pass.理由就不说了。。最近嫌弃结构体代码量略多..转战数组模拟...方便了很多&&写起来比较简单,但是!万一你跪了,查错是一件痛苦的事情..经常在晚上找错找到12点又滚回结构体了。。PS:遇到这种代码量大且繁琐的渣渣连define都不敢用了。。

#include<stdio.h>
#include<string.h>
#include<cmath> 
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<climits>
using namespace std;
#define F(n) for(int i = 0;i < n; i++)
#define FF(n) for(int i = 1;i <= n; i++)
#define f(n) for(int j = 0;j < n; j++)
#define ff(n) for(int j = 1;j <= n; j++) 
#define Met(n,m) memset(n, m, sizeof(n)) 
#define ll long long
const double P= acos(-1);
const int N=8050;

struct str{
	int l;
	int r;
	int rank;
};

str t[N*4];
int s
;

void build(int pos,int l,int r)
{
	t[pos].l=l,t[pos].r=r;
	t[pos].rank=-1;
	if(t[pos].r == t[pos].l)return;
	int mid =(l + r)/2;
	build(pos<<1,l,mid);
	build((pos<<1)+1,mid+1,r);
}

void pushdown(int pos)
{
	if(t[pos].rank != -1)
	{
		t[pos<<1].rank=t[pos].rank;
		t[(pos<<1)+1].rank=t[pos].rank;
		t[pos].rank=-1;
	}
}

void update(int l,int r,int pos ,int val)
{
	if(t[pos].l >= l && t[pos].r <= r)
	{
		t[pos].rank=val;
		return ;
	}
	pushdown(pos);
	int mid = (t[pos].r + t[pos].l)/2;
	if(r <= mid)  
       update(l , r ,  pos<<1,val );  
    else if(l > mid)  
       update(l , r , (pos<<1)+1, val);  
    else{  
       update(l , mid , pos<<1 ,  val);  
       update(mid+1 , r ,(pos<<1)+1, val);  
       }
}

int q(int pos,int x)
{
	if(t[pos].l == t[pos].r)return t[pos].rank;
	pushdown(pos);
	int mid = (t[pos].l + t[pos].r)/2;
	if(x <= mid)   
        return q( pos<<1 ,x);  
    else  
        return q((pos<<1)+1 , x);
}

int main()
{
	int n ,r, l , rank ,pre ,tmp;
	int minn,maxn;
	while(~scanf("%d",&n))
	{
		Met(s,0);
		minn = INT_MAX;
		maxn = INT_MIN;
		build(1,1,N);
		F(n){
			scanf("%d%d%d",&l,&r,&rank);
			
			minn = min(minn,l);
			maxn = max(maxn,r);
			l++;
			update(l,r,1,rank);
		   }
       pre = q(1 ,minn+1);
       s[pre]++;
      for(int i=minn +2;i<= maxn; i++)
      {
      	  tmp=q(1,i);
      	if(tmp != pre)
      	{
	      	s[tmp]++;
	      	pre=tmp;
	      }
      }
      
      for(int i = 0; i< N; i++)
      {
      	if(s[i])
      	{
	      	printf("%d %d\n",i,s[i]);
	      }
      }
      printf("\n");
      
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: