HDU 1698 <线段树+更新区间>

the reason of failure:1、多组数据,所以每次输出的值sum需要赋值0,然后才把金属棒的值相加后输出。

2、!!!看好输出的样例,不简简单单只是输出个答案,而是输出一串。

3、对于一个树形的数组,需要开结点*3的大小

thinking:用一个值来表示每个线段的值,当为各种值的时候其为0,当这个线段只为一种颜色的时候,其不为0。

对于更新时,当这个线段非0,那么把其两个son结点的k变为这个结点的k,然后把这个结点的k变为0(无论其本身是2,而更新某内部个结点也是2,也把其变为0)。

这样就能把仅更新的那个结点(或者说那个结点代表的线段)的k改变,而其他的值不改变。因为是更新线段,那么就不用每次都搜索到底层改变每一个点的值,所以速度非常快。

查找就找全部,如果这个点的k非0,那么就把这个这整个线段的值都计算,如果为0,那么就找其两个孩子搜索下去。

代码:

#include <iostream>
#include <string.h>
using namespace std;
struct ttt{
    int left,right,type;
};
ttt tree[100000*4+5];//需要开的数组大小为结点数*3
int sum;
void init(int x,int y,int num){
    tree[num].left=x;
    tree[num].right=y;
    if(tree[num].left==tree[num].right)
        tree[num].type=1;
    else{
        init(x,(x+y)/2,num+num);
        init((x+y)/2+1,y,num+num+1);
        tree[num].type=1;      //刚开始全部是纯色。
    }
}
void bian(int x,int y,int k,int num){
    if(tree[num].left>=x&&tree[num].right<=y){
        tree[num].type=k;
    //    cout << "结点"<<num<<"\t"<<tree[num].left <<" 到 " << tree[num].right<< " 变成了" << k << endl;
        return ;              //因为区间肯定刚开始小于
    }
    if(tree[num].type){          //即便是相同颜色,也把其变杂。
        tree[num+num].type=tree[num+num+1].type=tree[num].type;
        tree[num].type=0;
    }
    if((tree[num].left+tree[num].right)/2<x){
        bian(x,y,k,num+num+1);
    }else if((tree[num].left+tree[num].right)/2>=y){
        bian(x,y,k,num+num);
    }else{
        bian(x,y,k,num+num);
        bian(x,y,k,num+num+1);
    }
}
void find1(int num){
   // cout << num << "是" << tree[num].type << endl;
    if(tree[num].type){
        sum+=(tree[num].right-tree[num].left+1)*tree[num].type;
     //   cout << num<<"  从"<<tree[num].left<<" 到 " << tree[num].right << " 是" << tree[num].type <<endl;
        return ;
    }
    find1(num+num);
    find1(num+num+1);
}
int main(){  //线段树整段操作,快就快在改变一个区间的值仅仅为改变一个点的值,
    freopen("in.txt","r",stdin);
    int n,m,i,j,k,l,t1,t2,t3,f1,f2,T;
    cin >> T;
    int tt=T;
    while(T--){
    cin >> n;
    memset(tree,0,sizeof(tree));
    init(1,n,1);
    cin >> m;
    sum=0;      //多组数据要注意初始化。
    while(m--){
        scanf("%d%d%d",&t1,&t2,&t3);
        bian(t1,t2,t3,1);    //直接变一个区间,而不再是一个点。
    }
        find1(1);
        printf("Case %d: The total value of the hook is %d.\n",tt-T,sum);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值