题意: 给你a,b,c,在a,b区间内覆盖c,求最终的和........
这一题我也是醉了........
想了好久,一直不知道怎么更新成段更新区间.....后来看了标程,才做出来的.......
代码敲完,提交RE.....然后我就看啊看.....在移位的地方加了括号(真是作死,,,,,,)
期间我一直在纠结用+替换|会不会超时........
后来提交又TLE,,,,,,,,,,nimei....不是说加了ios可以的吗.....
.....
反正后来A了,是很无语的A掉,,,,,,,题目做的我蛋疼........
AC代码:
#include <iostream>
#include <stdio.h>
//#define Max 100010;
using namespace std;
const int Max = 100010;
struct S
{
int l,r,lazy,flag,sum;
};
S segtree[Max*3];
void build(int i,int l,int r)//初始化线段树
{
segtree[i].l=l;//初始化变量....
segtree[i].r=r;
segtree[i].lazy=0;
segtree[i].flag=0;
if(l==r) //到达叶子节点,递归结束(一开始我把结束条件放到前面....就会报错....后来想了下,自己好笨哦!!!!)
{
segtree[i].sum=1; //把每个节点都初始化sum=1
return;
}
int m=(l+r)>>1;
build(i<<1,l,m); //递归左子树
build((i<<1)+1,m+1,r);//递归右子树
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)+1].sum;//初始化节点sum和
}
void update(int i,int l,int r,int v)//更新节点(区间更新)
{
int m=(segtree[i].r+segtree[i].l)>>1;
if(segtree[i].l==l&&segtree[i].r==r) //这里是延迟标记的判断处,对每次读入的数据都会进行一次调用,
{
//作用是后面数据不用处理到叶子节点.......(就是线段树的优势吧....)
segtree[i].lazy=1; //标记
segtree[i].flag=v;
segtree[i].sum=(r-l+1)*v;//记下此段区间的和
return;
}
if(segtree[i].lazy==1) //因为第一组数据不会调用,所以只是方便后面处理
{
segtree[i].lazy=0; //调用完后,初始化重新标记
update(i<<1,segtree[i].l,m,segtree[i].flag); //所以这里要从segtree[i]开始递归
update((i<<1)+1,m+1,segtree[i].r,segtree[i].flag);
segtree[i].flag=0;
}
if(m>=r) //在没有进入lazy下,只需要判断m在(l,r)区间的情况.....然后进行递归更新
update(i<<1,l,r,v);
else if(m<l)
update((i<<1)+1,l,r,v);
else
{
update(i<<1,l,m,v);
update((i<<1)+1,m+1,r,v);
}
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)+1].sum;//同理,仍需要处理sum和问题
}
int main()
{
//ios::sync_with_stdio;
int t;
int n,m,a,b,c,k=0;
//cin>>t;
scanf("%d",&t);
while(t--)
{
//cout<<1;
//cin>>n>>m;
scanf("%d%d",&n,&m);
build(1,1,n);//从第一个节点开始,节点为1-n
//cout<<1;
while(m--)
{
//cin>>a>>b>>c;
scanf("%d%d%d",&a,&b,&c);
update(1,a,b,c);
//cout<<1;
}
//cout<<1;
//cout<<"Case "<<++k<<": The total value of the hook is "<<segtree[1].sum<<endl;
printf("Case %d: The total value of the hook is %d.\n",++k,segtree[1].sum);
}
return 0;
}