POJ 1698

Just a Hook

题意:

给出一个区间N,开始区间内的每一点值都是1

然后给出更新命令Q条,更新区间[x , y]的值为z

求出区间N的总价值(长度 * 价值)

-----------------------------------------------------

看到1<=N<=100,000  ,  0<=Q<=100,000

显然一般的n^2算法必然会超时,故需要高效算法

之前写过一个线段树(本题为这辈子写的第二个线段树),貌似差不多,故想到线段树

特点:区间大,成段更新,查询区间总和,综合这些特点,线段树满足!

代码参考了某博主的……

贴上供以后复习用

View Code
#include <cstdio>
#define N 400000

struct node
{
    int l , r;
    int num , value; // num:区间长度的总价值 
} tree[N];

int z;

void make(int s , int t , int rt) // 建树! 
{
     tree[rt].l = s;
     tree[rt].r = t;
     int mid = (s + t) / 2;
     tree[rt].num = t - s + 1;
     tree[rt].value = 1;
     if (s == t) return;
     make(s , mid , 2 * rt);
     make(mid + 1 , t , 2 * rt + 1);
}

void change(int x , int y , int rt)
{
     if (tree[rt].value == z) return;  // 临界条件 
     
     if (x == tree[rt].l && tree[rt].r == y)   // 找到某一区间,恰好符合 ,则最好 
     {
         tree[rt].value = z;
         tree[rt].num = (tree[rt].r - tree[rt].l + 1) * tree[rt].value;
         return;
     }
     
     if (tree[rt].value > 0)   // 当前根不满足所找区间,则向下层扫描 
     {
         tree[rt * 2].value = tree[rt].value;  // 左子树 
         tree[rt * 2].num = (tree[rt * 2].r - tree[rt * 2].l + 1) * tree[rt * 2].value;
         
         tree[rt * 2 + 1].value = tree[rt].value;  // 右子树 
         tree[rt * 2 + 1].num = (tree[rt * 2 + 1].r - tree[rt * 2 + 1].l + 1) * tree[rt * 2 + 1].value;
         
         tree[rt].value = 0;  // 找过了,清零 
     }
     
     int mid = (tree[rt].l + tree[rt].r) / 2;
     if (x > mid) change(x , y , rt * 2 + 1);
     else if (y <= mid) change(x , y , rt * 2);
     else
     {
         change(x , mid , rt * 2);
         change(mid + 1 , y , rt * 2 + 1);
     }
     tree[rt].num = tree[rt * 2].num + tree[rt * 2 + 1].num;  // 将左右子树的值加到根上 
}
         

int main()
{
    int T , n , Q , x , y;
    int time = 0;
    
    scanf("%d" , &T);
    while (T --)
    {
        scanf("%d" , &n);
        make (1 , n , 1);
        scanf("%d" , &Q);
        while (Q --)
        {
            scanf("%d%d%d" , &x , &y , &z);
            change(x , y , 1);
        }
        printf("Case %d: The total value of the hook is %d.\n" , ++time , tree[1].num);
    }
    return 0;
}

 

 

posted on 2013-02-05 23:47  Hmm  阅读(248)  评论(0编辑  收藏  举报

导航