Just a Hook(线段树,成段更新)

    科技2024-03-23  85

    题目传送门

    Just a Hook

    题目大意

    T组数据 每组有一个长度为n的序列,给你m次操作,每次操作给你x,y,z三个数,操作:将x到y的数字变为z m次操作完成后求序列的总和

    思路

    很明显的线段树题目,维护区间和即可 注意一下更新区间的方法即可: 对于修改不能直接更新到底部,要成段更新

    AC Code

    #include<bits/stdc++.h> using namespace std; #define debug(a) cout<<#a<<"="<<a<<endl; const int N=1e5 +9; int T, n, m, x, y ,z; struct segtree{ int l, r; int sum, tag; }tr[N<<2]; inline int read() { int ans=0; char last=' ',ch=getchar(); while(ch<'0'||ch>'9') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } inline int lc(int p) {return p<<1;} inline int rc(int p) {return p<<1|1;} inline void push_up(int p) {tr[p].sum=tr[lc(p)].sum+tr[rc(p)].sum;} inline void build(int p, int l, int r){ tr[p].l=l, tr[p].r=r; tr[p].tag=tr[p].sum=0; if(l==r) {tr[p].sum=1; return ;} int mid=(l+r)>>1; build(lc(p), l, mid); build(rc(p), mid+1, r); push_up(p); } inline void f(int p, int k){ tr[p].sum=k*(tr[p].r-tr[p].l+1); tr[p].tag=k; } inline void push_down(int p){ f(lc(p), tr[p].tag); f(rc(p), tr[p].tag); tr[p].tag=0; } inline void updata(int p, int l, int r, int x, int y, int k){ if(x>r || y<l) return ; if(l<=x && y<=r){ tr[p].sum=k*(y-x+1); tr[p].tag=k; return ; } if(tr[p].tag) push_down(p); int mid=(x+y)>>1; updata(lc(p), l, r, x, mid, k); updata(rc(p), l, r, mid+1, y, k); push_up(p); } int main(){ T=read(); int k=0; while(T--){ n=read(); m=read(); memset(tr, 0, sizeof(tr)); build(1,1,n); for(int i=1; i<=m; i++){ x=read(); y=read(); z=read(); updata(1,x,y,1,n,z); } printf("Case %d: The total value of the hook is %d.\n", ++k, tr[1].sum); } return 0; }
    Processed: 0.027, SQL: 8