HDU ACM 1698 Just a Hook->线段树+区间修改

来源:互联网 发布:淘宝如何做爆款 编辑:程序博客网 时间:2024/05/20 08:45

分析:线段树的应用,区间修改,使用延迟标记进行延迟修改。

#include<iostream>using namespace std;#define N 100010class SegmentTree{private:struct Node{int left,right;     //左右子节点int sum;            //区间和int lazy;           //延迟标记};public:void BuildTree(int root,int l,int r);void Change(int root,int l,int r,int c);int Query(int root);private:Node m_Tree[N<<2];};int SegmentTree::Query(int root){return m_Tree[root].sum;}void SegmentTree::Change(int root,int l,int r,int c){int mid,x,y;x=m_Tree[root].left;y=m_Tree[root].right;if(l==x && r==y){m_Tree[root].lazy=1;m_Tree[root].sum=(y-x+1)*c;   //区间的每个点都被修改为c,和就等于点数乘以creturn ;}mid=(x+y)>>1;if(m_Tree[root].lazy==1)    //该if处理延迟更新{m_Tree[root].lazy=0;Change(2*root+1,x,mid,m_Tree[root].sum/(y-x+1));  //m_Tree[root].sum/(r-l+1)即可得到之前保留的单个点的值Change(2*root+2,mid+1,y,m_Tree[root].sum/(y-x+1));}if(l<=mid) Change(2*root+1,l,mid<r?mid:r,c);    //该两句更新包含三种情况,更新区间在mid左边,在右边,左右两边均有if(r>mid) Change(2*root+2,mid+1>l?mid+1:l,r,c);m_Tree[root].sum=m_Tree[root*2+1].sum+m_Tree[root*2+2].sum;}void SegmentTree::BuildTree(int root,int l,int r){int mid;m_Tree[root].left=l;m_Tree[root].right=r;m_Tree[root].sum=r-l+1;     //刚开始区间和等于区间的点数m_Tree[root].lazy=1;        //设置延迟标记if(l==r) return ;mid=(l+r)>>1;BuildTree(2*root+1,l,mid);     //构建左子树BuildTree(2*root+2,mid+1,r);   //构建右子树}SegmentTree seg_tree;int main(){int T,n,Q,X,Y,Z,i;scanf("%d",&T);i=0;while(T--){scanf("%d",&n);seg_tree.BuildTree(0,0,n-1);scanf("%d",&Q);while(Q--){scanf("%d %d %d",&X,&Y,&Z);seg_tree.Change(0,X-1,Y-1,Z);}printf("Case %d: The total value of the hook is %d.\n",++i,seg_tree.Query(0));}return 0;}


0 0
原创粉丝点击