题意:一条长链子上面有许多钩子,一次编号 1 - n ,每个钩子有金银铜三种材质(3,2,1),假设一开始全是铜质的,每次操作可以将 x - y 范围内的钩子变成 z 材质.求最后整条链子的值。
题解:lazy标记
#include <cstring> #include <iostream> using namespace std; #define L(u) ( u << 1 ) #define R(u) ( u << 1 | 1 ) #define N 100005 struct item { int l, r, v, kind; } node[N*3]; void build ( int u, int l, int r ) { node[u].l = l; node[u].r = r; node[u].v = r - l + 1; node[u].kind = 1; if ( l == r ) return; int mid = ( l + r ) >> 1; build ( L(u), l, mid ); build ( R(u), mid + 1, r ); } void update ( int u, int l, int r, int val ) { if ( node[u].kind == val ) return; // 材质相同则没必要修改了 if ( l <= node[u].l && node[u].r <= r ) { node[u].v = ( node[u].r - node[u].l + 1 ) * val; node[u].kind = val; return; } if ( node[u].kind != 0 ) { node[L(u)].kind = node[u].kind; node[L(u)].v = ( node[L(u)].r - node[L(u)].l + 1 ) * node[L(u)].kind; node[R(u)].kind = node[u].kind; node[R(u)].v = ( node[R(u)].r - node[R(u)].l + 1 ) * node[R(u)].kind; node[u].kind = 0; } int mid = ( node[u].l + node[u].r ) >> 1; if ( r <= mid ) update ( L(u), l, r, val ); else if ( l > mid ) update ( R(u), l, r, val ); else { update ( L(u), l, mid, val ); update ( R(u), mid+1, r, val ); } node[u].v = node[L(u)].v + node[R(u)].v; } int main() { int t, n, q, l, r, kind; scanf("%d",&t); for ( int i = 1; i <= t; i++ ) { scanf("%d",&n); build ( 1, 1, n ); scanf("%d",&q); while ( q-- ) { scanf("%d%d%d",&l,&r,&kind); update ( 1, l, r, kind ); } printf("Case %d: The total value of the hook is %d.\n", i, node[1].v ); } return 0; }