转换成区间染色问题吧。。。。
给你一个区间,默认是第一种色,然后再给出一个区间以及一种颜色开始染,最后是求出整个区间上所有颜色的价值是多少,三种色,1,2,3
类似于区间求和问题,常规不能用依旧需要保持一个增量来做,还有个办法就是区间染色问题来做,维持区间的颜色和不是和,最后get把每个区间段的颜色求出
最后再求个和就ok...
区间求和
#include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <climits> #define L(x) (x << 1) #define R(x) (x << 1 | 1) using namespace std; const int MAX = 100010; struct Tnode{ int val,a; int l,r;}; Tnode node[MAX*4]; void init() { memset(node,0,sizeof(node)); } void build(int t,int l,int r) { node[t].l = l; node[t].r = r; if(l==r-1) { node[t].val = 1; return ; } int mid = ( l + r ) >> 1; build(L(t), l, mid); build(R(t), mid, r); node[t].val=node[L(t)].val+node[R(t)].val; } void update(int t,int l,int r,int val) { if( node[t].l==l && node[t].r==r ) { node[t].a+=val; node[t].val = val*(r-l); return ; } if(node[t].a) { node[L(t)].a+=node[t].a; node[R(t)].a+=node[t].a; node[R(t)].val += node[t].a*(node[R(t)].r - node[R(t)].l); node[L(t)].val += node[t].a*(node[L(t)].r - node[L(t)].l); node[t].a=0; } int mid = (node[t].l + node[t].r) >> 1; if( l >=mid ) update(R(t),l,r,val); else if( r <= mid ) update(L(t),l,r,val); else { update(R(t),mid,r,val); update(L(t),l,mid,val); } node[t].val=node[L(t)].val+node[R(t)].val; } int get(int t,int l,int r) { if( node[t].l == l && node[t].r ==r ) { return node[t].val; } if(node[t].a) { node[L(t)].a+=node[t].a; node[R(t)].a+=node[t].a; node[R(t)].val += node[t].a*(node[R(t)].r - node[R(t)].l); node[L(t)].val += node[t].a*(node[L(t)].r - node[L(t)].l); node[t].a=0; } int mid = (node[t].l + node[t].r) >> 1; if( l >= mid ) return get(R(t),l,r); else if( r <= mid ) return get(L(t),l,r); else { return get(R(t),mid,r)+get(L(t),l,mid); } } int main() { int n,m,x,y,val,ind=1; char str[5]; int T; scanf("%d",&T); while(T-- ) { init(); scanf("%d%d",&n,&m); build(1,1,n+1); while( m-- ) { scanf("%d%d%d",&x,&y,&val); update(1,x,y+1,val); } printf("Case %d: The total value of the hook is %d.\n",ind++,get(1,1,n+1)); } return 0; }
区间染色
/*Author:zxy_snow*/ #include <cmath> #include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <climits> #define MID(x,y) ((x+y)>>1) #define L(x) (x<<1) #define R(x) (x<<1|1) using namespace std; const int MAX = 100010; struct Tnode{int sum,l,r;}; Tnode node[MAX*4]; void init() { memset(node,0,sizeof(node)); } void Build(int t,int l,int r) { node[t].sum = 1; node[t].l = l; node[t].r = r; if( l == r - 1 ) return ; int mid = MID(l,r); Build(R(t),mid,r); Build(L(t),l,mid); } void Updata(int t,int l,int r,int sum) { if( node[t].l == l && node[t].r == r ) { node[t].sum = sum; return ; } if( node[t].sum > 0 ) { node[R(t)].sum = node[t].sum; node[L(t)].sum = node[t].sum; node[t].sum = -1; } int mid = MID(node[t].l,node[t].r); if( l >= mid ) Updata(R(t),l,r,sum); else if( r <= mid ) Updata(L(t),l,r,sum); else { Updata(L(t),l,mid,sum); Updata(R(t),mid,r,sum); } } int Query(int t,int l,int r) { if( node[t].sum > 0 ) return node[t].sum * (r - l); int mid = MID(node[t].l,node[t].r); if( l >= mid ) return Query(R(t),l,r); else if( r <= mid ) return Query(L(t),l,r); else return Query(L(t),l,mid) + Query(R(t),mid,r); } int main() { int ncases,ind = 1,n,m,x,y,z; scanf("%d",&ncases); while( ncases-- ) { scanf("%d%d",&n,&m); init(); Build(1,0,n); while( m-- ) { scanf("%d%d%d",&x,&y,&z); Updata(1,x-1,y,z); } printf("Case %d: The total value of the hook is %d.\n",ind++,Query(1,0,n)); } return 0; }