【HDU1698】 Just a Hook 【線段樹入門】
阿新 • • 發佈:2018-08-20
uil 機器 連續 fin case using -- pre 上一個
原題:原題鏈接
題意:(機器翻譯的...)
讓我們將鉤子的連續金屬棒從1到N編號。對於每次操作,Pudge可以將連續的金屬棒(從X到Y編號)改為銅棒,銀棒或金棒。
鉤的總值計算為N個金屬棒的值的總和。更確切地說,每種棒的值計算如下:
對於每個銅棒,值為1.
對於每個銀棒,值為2.
對於每個金棒,值為3.
Pudge想知道執行操作後鉤子的總值。
你可能會認為原來的鉤子是由銅棒組成的。
【思路】
線段樹-區間更新lazy_tag
PS:原來都是1,不是0,因為這個卡了好久
#include<iostream> #include<cstdio> #include<cctype> #include<algorithm> #define MAXN 100005 using namespace std; inline int read() { char chr=getchar(); int f=1,ans=0; while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();} while(isdigit(chr)) {ans=ans*10;ans+=chr-'0';chr=getchar();} return ans*f; } struct node{ int l,r; int val,lazy; int mid(){ return l+r>>1; } }t[MAXN<<2]; int a[MAXN]; int n,m; void push_up(int x){//上傳 t[x].val=t[x<<1].val+t[x<<1|1].val; } void push_down(int x){//下傳 if(t[x].lazy){ t[x<<1].lazy=t[x].lazy; t[x<<1|1].lazy=t[x].lazy;//如果是加上一個數的話,要寫+=,改成一個數的話直接等於 t[x<<1].val=(t[x<<1].r-t[x<<1].l+1)*t[x<<1].lazy; t[x<<1|1].val=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x<<1|1].lazy; t[x].lazy=0; } } void build(int i,int l,int r){//建樹 t[i].l=l; t[i].r=r; t[i].lazy=0; if(l==r){ t[i].val=1;//初始銅棒——》 1 return; } build(i<<1,t[i].l,t[i].mid()); build(i<<1|1,t[i].mid()+1,t[i].r); push_up(i); } void updata(int i,int l,int r,int v){//更新 if(l<=t[i].l && t[i].r<=r){ t[i].val=(t[i].r-t[i].l+1)*v;//這裏要註意(r-l+1)*v,不是v t[i].lazy=v; return; } push_down(i);//記得下傳 int m=t[i].mid(); if(l<=m) updata(i<<1,l,r,v); if(r>m) updata(i<<1|1,l,r,v); push_up(i);//... } int query(int i,int l,int r){ if(l<=t[i].l && t[i].r<=r) return t[i].val; push_down(i);//敲黑板:這裏不要忘了 int m=t[i].mid(); int sum=0; if(l<=m) sum+=query(i<<1,l,r); if(m<r) sum+=query(i<<1|1,l,r); push_up(i); return sum; } int T; int main() { T=read(); int tot=0; while(T--){ n=read(); build(1,1,n); m=read(); while(m--){ int x=read(),y=read(),v=read(); updata(1,x,y,v);//更新 } printf("Case %d: The total value of the hook is %d.\n",++tot,query(1,1,n));//格式很強 } return 0; }
【HDU1698】 Just a Hook 【線段樹入門】