这是怎么了

P3372 【模板】线段树 1

the_heir_of_Rome @ 2023-06-28 18:50:46

rt,样例都过不了 CODE

求调


by ducati @ 2023-06-28 18:55:56

if(le <= tree[i].l&& ri >= tree[i].r)
{
    tree[i].sum+=(long long)k*(tree[i].r + tree[i].l+1);
    tree[i].tg += k ;
    return;
}

你确定是 tree[i].r + tree[i].l + 1


by the_heir_of_Rome @ 2023-06-28 19:06:11

@ducati

样例的最后一个输出还是16


by Azure_Space @ 2023-06-28 19:15:41

你有三个地方符号打错了,帮你改好了

# include <bits/stdc++.h>
//#define int long long
using namespace std ;
struct node
{
    long long sum , tg , l , r ;
}tree[400040];
long long a[100010] ;
void push_down(long long i)
{
    if(tree[i].tg)//我有懒标记 
    {
        tree[i*2].sum += tree[i].tg * (tree[i*2].r - tree[i*2].l+1);//计算左孩子与右孩子的和 
        //tree[i*2].sum == tree[i].tg * (tree[i*2].r - tree[i*2].l+1);//计算左孩子与右孩子的和 
        tree[i*2+1].sum += tree[i].tg * (tree[i*2+1].r - tree[i*2+1].l+1);
        //tree[i*2+1].sum == tree[i].tg * (tree[i*2+1].r - tree[i*2+1].l+1);
        tree[i*2].tg += tree[i].tg ;//把懒标记给我的左孩子,右孩子 
        tree[i*2+1].tg += tree[i].tg ;
        tree[i].tg = 0 ;
    }
}
void build(int i , int le , int ri)//树的第i个点 
{
    tree[i].l = le ;
    tree[i].r = ri ;
    tree[i].tg = 0 ;//懒标记   
    if(le == ri)
    {
        tree[i].sum = a[le]; 
        return;
    }
    int mid = (le+ri)>>1 ;
    build(i*2 , le , mid) ;//左孩子 
    build(i*2+1,mid+1,ri) ;//右孩子 
    tree[i].sum = tree[i*2].sum + tree[i*2+1].sum ; 
}
void add(int i , int le , int ri , long long k)
{
    if(le <= tree[i].l&& ri >= tree[i].r)
    {
        tree[i].sum+=(long long)k*(tree[i].r - tree[i].l+1);
        //tree[i].sum+=(long long)k*(tree[i].r + tree[i].l+1);
        tree[i].tg += k ;
        return;
    }
    push_down(i) ;
    int mid = (tree[i].l + tree[i].r)/2 ;
    if(le <= mid)
    {
        add(i*2 , le , ri , k) ;
    }
    if(ri > mid)
    {
        add(i*2+1 , le , ri , k) ;
    }
    tree[i].sum = tree[i*2].sum + tree[i*2+1].sum ;
}
int ask(int i , int le , int ri)
{
    if(le <= tree[i].l && ri >= tree[i].r)
    {
        return tree[i].sum ;
    }
    push_down(i) ;
    int sss = 0 ;
    int mid = (tree[i].l + tree[i].r)/2 ;
    if(le <= mid)
    {
        sss += ask(i*2 , le , ri) ;
    }
    if(ri > mid)
    {
        sss += ask(i*2+1 , le , ri) ;
    }
    return sss ;
}
int main()
{
    long long n , m , o , x , y , k ;
    cin >> n >> m ;
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> a[i] ;
    }
    build(1,1,n) ;
    while(m--)
    {
        cin >> o ;
        if(o == 1)//加上数 
        {
            cin >> x >> y >> k ;
            add(1,x,y,k);   
        }
        else//区间求和 
        {
            cin >> x >>y;
            cout << ask(1,x,y) << endl ;    
        }
    }
    return 0;
}

by the_heir_of_Rome @ 2023-06-28 22:07:05

@youjikai

大佬,非常感谢,已经关注了


|