码迷,mamicode.com
首页 > 其他好文 > 详细

线段树区间更新1

时间:2018-08-25 13:56:40      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:lin   lis   \n   stream   str   线段   --   std   bsp   

https://www.luogu.org/problemnew/show/P3372
/*
第八个测试数据有问题(已看)
https://www.luogu.org/problemnew/show/P3372

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和


*/
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <time.h>
#include <string>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <ext/rope>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
#define pi 3.1415926536
#define E  2.7182818284
const ll mod=1e9+7;//998244353
const int maxn=1e5+10;

ll sum[maxn<<2],tag[maxn<<2];

void build(int index,int l,int r)
{
    tag[index]=0;
    if (l==r)
        scanf("%lld",&sum[index]);
    else
    {
        int m=(l+r)>>1;
        build(index<<1,l,m);
        build(index<<1|1,m+1,r);
        sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
    }
}

void pushdown(int index,int len)
{
    sum[index<<1]=(tag[index]*((len+1)>>1) +sum[index<<1])%mod;
    sum[index<<1|1]=(tag[index]*(len>>1) +sum[index<<1|1])%mod;
    tag[index<<1]=(tag[index]+ tag[index<<1])%mod;
    tag[index<<1|1]=(tag[index]+ tag[index<<1|1])%mod;
    tag[index]=0;
}

void update(int index,int l,int r,int x,int y,ll k)
{
    if (x<=l && r<=y)
    {
        sum[index]=(k*(r-l+1) +sum[index])%mod;
        tag[index]=(k +tag[index])%mod;
    }
    else
    {
        int m=(l+r)>>1;
        if (tag[index]!=0)
            pushdown(index,r-l+1);
        if (x<=m)
            update(index<<1,l,m,x,y,k);
        if (m<y)
            update(index<<1|1,m+1,r,x,y,k);
        sum[index]=(sum[index<<1]+sum[index<<1|1])%mod;
    }
}

ll query(int index,int l,int r,int x,int y)
{
    if (x<=l && r<=y)
        return sum[index];
    if (tag[index]!=0)
        pushdown(index,r-l+1);
    if (r<x || l>y)
        return 0;
    int m=(l+r)>>1;
    return (query(index<<1,l,m,x,y)+query(index<<1|1,m+1,r,x,y))%mod;
}

int main()
{
    int n,m,mode,x,y;
    ll k;
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while (m--)
    {
        scanf("%d",&mode);
        if (mode==1)
        {
            scanf("%d%d%lld",&x,&y,k);
//            if  (x==8643   && y==60450)
//            {
//                printf("zzz\n");
//            }
            update(1,1,n,x,y,k%mod);
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}
/*
8 10
659 463 793 740 374 330 772 681
1 5 8 39
2 5 8
1 3 6 3
1 5 8 90
1 1 5 21
2 3 8
1 3 8 17
1 4 7 52
2 2 6
1 2 7 41

5 5
1 2 3 4 5
1 1 3 -1
1 1 3 1
2 2 4

10 100
1 2 3 4 5 6 7 8 9 10
2 1 10
1 2 7 1
2 1 10
2 3 8

*/

 

线段树区间更新1

标签:lin   lis   \n   stream   str   线段   --   std   bsp   

原文地址:https://www.cnblogs.com/cmyg/p/9533201.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!