题意:胖子有一条大jb,大JB由n个小JB组成,每次操作将一个区间的小JB变成金银铜三者之一,最后取出所有区间的JB总价值
思路:和刷气球差不多意思了,简单的区间更新,无需更新到叶子节点,防止超时
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <algorithm> using namespace std; #define M 100005 #define ls node<<1,l,m #define rs node<<1|1,m+1,r int n,m,tree1[M<<2],tree2[M<<2]; void pushdown(int node,int m) { if(tree1[node]) { tree1[node<<1]=tree1[node<<1|1]=tree1[node]; tree2[node<<1]=(m-(m>>1))*tree1[node]; tree2[node<<1|1]=(m>>1)*tree1[node]; tree1[node]=0; } } void buildtree(int node,int l,int r) { tree1[node]=0; tree2[node]=1; if(l==r) return ; int m=(l+r)>>1; buildtree(ls); buildtree(rs); tree2[node]=tree2[node<<1]+tree2[node<<1|1]; } void update(int L,int R,int c,int node,int l,int r) { if(L<=l&&r<=R) { tree1[node]=c; tree2[node]=c*(r-l+1); return ; } pushdown(node,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,c,ls); if(R>m) update(L,R,c,rs); tree2[node]=tree2[node<<1]+tree2[node<<1|1]; } int main() { //freopen("in.txt","r",stdin); int t,cas=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); buildtree(1,1,n); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,1,n); } printf("Case %d: The total value of the hook is %d. ",cas++,tree2[1]); } return 0; }