HDU 1698 Just a Hook (线段树区间更新)
生活随笔
收集整理的這篇文章主要介紹了
HDU 1698 Just a Hook (线段树区间更新)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意 : 一個有n段長的金屬棍,開始都涂上銅,分段涂成別的,金的值是3,銀的值是2,銅的值是1,然后問你最后這n段總共的值是多少。
思路 : 線段樹的區間更新。可以理解為線段樹成段更新的模板題。
//HDU 1698
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std; int lz[],p[] ; //lz延遲標記,每次更新不需要更新到底,使得更新延遲到下次更新或者查詢的時候
void pushdown(int rt,int m)
{
if(lz[rt])
{
lz[rt << ] = lz[rt] ;
lz[rt << | ] = lz[rt] ;
p[rt << ] = (m -( m >> )) * lz[rt] ;
p[rt << | ] = (m>>) * lz[rt] ;
lz[rt] = ;
}
}
void pushup(int rt) // 將左右孩子的值更新到自己
{
p[rt] = p[rt << ] + p[rt << | ] ;
} void update(int L,int R,int l,int r,int sc,int rt)
{
if(l >= L && r <= R)
{ lz[rt] = sc ;
p[rt] = (r-l+)*sc ;
return ;
}
pushdown(rt,r-l+) ;
int m = (r + l ) >> ;
if(m >= L)
update(L,R,l,m,sc,rt << ) ;
if(R > m)
update(L,R,m+,r,sc,rt << | ) ;
pushup(rt) ;
}
void build(int l,int r,int rt)
{
lz[rt] = ;
if(l == r)
{
p[rt] = ;
return ;
}
int mid = (l + r) >> ;
build(l,mid,rt << ) ;
build(mid + ,r,rt << | ) ;
pushup(rt) ;
}
int query(int L,int R,int l,int r,int rt)
{
int sum = ;
if(L <= l && r <= R)
{ return p[rt] ;
}
pushdown(rt , r-l+) ;
int mid = (l + r) >> ;
if(mid >= L)
sum += query(L,R,l,mid,rt << ) ;
if(mid < R)
sum += query(L,R,mid+,r,rt << | ) ;
return sum ; }
int main()
{
int T,N,Q ;
cin >> T ;
int casee = ;
while(T--)
{
int x,y,z ;
cin >> N >> Q ;
build(,N,) ;
while(Q--)
{
cin >> x >> y >> z ;
update(x,y,,N,z,) ;
}
int sum = query(,N,,N,) ;
cout<<"Case "<< casee ++ <<": The total value of the hook is "<<sum <<"."<<endl ;
}
return ;
}
總結
以上是生活随笔為你收集整理的HDU 1698 Just a Hook (线段树区间更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: selenium 与appium的关系
- 下一篇: AtCoder Beginner Con