CSU——2151: 集训难度

Description

小L正在组织acm暑假集训,但众所周知,暑假集训的萌新中有OI神犇,也有暑假才开始学算法的萌新,如果统一集训的难度,无法很好地让萌新们得到训练,所以小L想了一个办法,根据每次测试的情况,改变萌新们的集训难度。现在将萌新们编号为1到n,最初萌新们的集训难度为v0,测试后有两种操作,第一种是某一区间的萌新的集训难度同时提高,另一种是将某一段区间的萌新的集训难度变为同一个数,同时,Wells希望在某次调整难度之后,知道某一段区间的萌新的集训难度之和,由于小L比较鶸,他并不知道如何快速解决这个问题,你能帮帮他嘛?

 

Input

第一行三个数n,m,v0 表示有n名萌新和m次调整,初始时全部萌新的集训难度都为v0

第2~m+1行 每行三个数或四个数

0 x y v 表示把 [x,y]区间内的萌新的集训难度都增加v

1 x y v 表示把 [x,y]区间内的萌新的集训难度都变为v

2 x y表示询问[x,y]区间内萌新的集训难度之和

0

Output

每个询问一行,输出答案

Sample Input

3 5 0
0 1 3 1
1 2 3 2
2 1 1  
2 2 2
2 2 3

Sample Output

1
2
4

wa,做这题心态爆炸,觉得自己改改应该就能过了,然后就两个小时过去了,然后就半个小时了,心想反正也没时间做其他的了,然后就爆零了。

这题其实是模板的线段树,只是有两个lazy标记,你pushdown的时候要考虑lazy之间的相互影响。设置两个lazy,lazy表示当前区间要全部加上lazy, lazy表示当前区间全被染成lazy,传递lazy的时候,如果lazy存在,那么如果子节点的lazy存在,那么直接往lazy2上加,如果没有,就往子节点的lazy1上加,传lazy2的时候,子节点的lazy1直接就清掉,然后lazy2就继承下来。

但是要注意pushdowm要放在最前面,每次change和query之前就要进行。还有lazy2要取一个取不到的值作为没有。

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn=100005;
const double eps=1e-8;
const double pi=acos(-1.0);
const int MOD=10056;
int T,n,m,v0;
int x,y,v;
int flag;
struct Node
{
    int l,r;
    LL sum,lazy1,lazy2;
}tree[maxn<<2];

void build(int k,int l,int r)
{
    tree[k].l=l;tree[k].r=r;tree[k].lazy1=0;tree[k].lazy2=INF;
    if(l==r)
    {
        tree[k].sum=v0;
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
void pushdown(int x)
{
    if(tree[x].lazy2!=INF)
    {
        tree[x<<1].lazy1=0;
        tree[x<<1|1].lazy1=0;
        tree[x<<1].lazy2=tree[x].lazy2;
        tree[x<<1|1].lazy2=tree[x].lazy2;
        tree[x<<1].sum=tree[x].lazy2*(tree[x<<1].r-tree[x<<1].l+1);
        tree[x<<1|1].sum=tree[x].lazy2*(tree[x<<1|1].r-tree[x<<1|1].l+1);
        tree[x].lazy2=INF;
    }
    if(tree[x].lazy1!=0)
    {
        if(tree[x<<1].lazy2!=INF)
        {
            tree[x<<1].lazy1=0;
            tree[x<<1].lazy2+=tree[x].lazy1;
            tree[x<<1].sum=tree[x<<1].lazy2*(tree[x<<1].r-tree[x<<1].l+1);
        }
        else
        {
            tree[x<<1].lazy1+=tree[x].lazy1;
            tree[x<<1].sum+=tree[x].lazy1*(tree[x<<1].r-tree[x<<1].l+1);
        }
        if(tree[x<<1|1].lazy2!=INF)
        {
            tree[x<<1|1].lazy1=0;
            tree[x<<1|1].lazy2+=tree[x].lazy1;
            tree[x<<1|1].sum=tree[x<<1|1].lazy2*(tree[x<<1|1].r-tree[x<<1|1].l+1);
        }
        else
        {
            tree[x<<1|1].lazy1+=tree[x].lazy1;
            tree[x<<1|1].sum+=tree[x].lazy1*(tree[x<<1|1].r-tree[x<<1|1].l+1);
        }
        tree[x].lazy1=0;
    }
}
void change(int k,int l,int r)
{
	pushdown(k);
    if(tree[k].l==l&&tree[k].r==r)
    {
        if(flag==0)
        {
            tree[k].lazy1+=v;
            tree[k].sum+=v*(r-l+1);
        }
        else
        {
            tree[k].lazy2=v;
            tree[k].lazy1=0;
            tree[k].sum=v*(r-l+1);
        }
        return ;
    }
    if(tree[k].l==tree[k].r)
        return;
    int mid=(tree[k].l+tree[k].r)>>1;
    if(mid>=r)
        change(k<<1,l,r);
    else if(mid>1;
    if(r<=mid)
        maxx+=query(k<<1,l,r);
    else if(l>=mid+1)
        maxx+=query(k<<1|1,l,r);
    else
    {
        maxx+=query(k<<1,l,mid);
        maxx+=query(k<<1|1,mid+1,r);
    }
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
    return maxx;
}
int main()
{
    scanf("%d %d %d",&n,&m,&v0);
    build(1,1,n);
    while(m--)
    {
        scanf("%d",&flag);
        if(flag==2)
        {
            scanf("%d %d",&x,&y);
//            for(int i=1;i<=n;i++)
//                printf("%d ",tree[i].sum);
//            printf("\n");
            printf("%lld\n",query(1,x,y));
        }
        else
        {
            scanf("%d %d %d",&x,&y,&v);
            change(1,x,y);
        }
    }
    return 0;
}
/*
9 4 8
0 2 8 4
0 7 7 3
1 1 3 7
2 3 8
*/

/**********************************************************************
	Problem: 2151
	User: jk1601zr
	Language: C++
	Result: AC
	Time:260 ms
	Memory:14524 kb
**********************************************************************/

 

你可能感兴趣的:(CSUOJ)