题目
现在,Pudge想在钩子上做一些操作。
让我们将钩子上连续的金属棒编号从1到n,每一次操作,Pudge都可以将编号从X到Y的连续金属棒改为铜棒、银棒或金棒。该钩的总价值计算为N根金属杆的总价值之和。更准确地说,每一种棍的值计算如下:对于每根铜棒,值是1。对于每根银棒,值是2。每根金棒的值是3。
Pudge想知道执行操作后钩子的总价值。你可以认为原来的钩子是用铜棒做的。
输入
输入由几个测试用例组成。输入的第一行是案例的数量。不超过10例。
对于每一种情况,第一行包含一个整数N, 1<=N<=100,000,这是Pudge’s meat hook的棍子数,第二行包含一个整数Q, 0<=Q<=100,000,这是操作数。
接下来的Q行,每行包含3个整数X, Y, 1<=X<=Y<=N, Z, 1<=Z<=3,定义了一个操作:将编号为X到Y的木棍改为金属型Z,其中Z=1表示铜类,Z=2表示银类,Z=3表示金类。
Sample Input
1
10
2
1 5 2
5 9 3
Sample Output
Case 1: The total value of the hook is 24.
emmm。区间染色 tag不需要上推。不管tag!=-1与否 都是要强行染色的。
#include <cstdio>
using namespace std;
const int N=100005*4;
int sum[N],tag[N];
void pushup(int pos)
{
sum[pos]=sum[pos<<1]+sum[pos<<1|1];
}
void build(int l,int r,int pos)
{
if(l==r)
{
tag[pos]=1;
sum[pos]=1;
return;
}
int mid=(l+r)>>1;
build(l,mid,pos<<1);
build(mid+1,r,pos<<1|1);
tag[pos]=1;
pushup(pos);
}
void pushdown(int ln,int rn,int pos)
{
if(tag[pos]==-1)
return;
tag[pos<<1]=tag[pos<<1|1]=tag[pos];
sum[pos<<1]=ln*tag[pos];
sum[pos<<1|1]=rn*tag[pos];
tag[pos]=-1;
}
void chanspan(int cl,int cr,int val,int l,int r,int pos)
{
if(cl<=l&&r<=cr)
{
tag[pos]=val;
sum[pos]=val*(r-l+1);
return;
}
int mid=(l+r)>>1;
pushdown(mid-l+1,r-mid,pos);
if(cl<=mid)
chanspan(cl,cr,val,l,mid,pos<<1);
if(cr>mid)
chanspan(cl,cr,val,mid+1,r,pos<<1|1);
pushup(pos);
}
int main()
{
int T;
scanf("%d",&T);
int cas=0;
while(T--)
{
++cas;
int n;
scanf("%d",&n);
build(1,n,1);
int q;
scanf("%d",&q);
while(q--)
{
int a,b,z;
scanf("%d%d%d",&a,&b,&z);
chanspan(a,b,z,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",cas,sum[1]);
}
}