线段树的应用与优化(注意此题更改数据后已tle)

来源:互联网 发布:网络机柜为什么用u 编辑:程序博客网 时间:2024/06/15 16:48

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828

题意:三种操作,1是区间加,2是区间开根号,3是区间求和。

分析:区间开根号,往往需要更新到底,但如果这个数组退化为相同的数。做一个区间内的数都相同的标记,即可。

#include <iostream>#include <cstdio>#include <cstring>#include <sstream>#include <string>#include <algorithm>#include <list>#include <map>#include <vector>#include <queue>#include <stack>#include <cmath>#include <cstdlib>#define L(u) (u<<1)#define R(u) (u<<1|1)//long longusing namespace std; struct Nodes{    int l,r;    long long  sum;    long long minx;    long long lazy;} node[800040]; int A[200009];void Pushup(int u){    node[u].sum = node[L(u)].sum + node[R(u)].sum;    node[u].minx = min(node[L(u)].minx , node[R(u)].minx);    return ;}void Update(int u,int left,int right,int val);void Pushdown(int n){    int mid = (node[n].l + node[n].r) / 2;    if(node[n].lazy != 0)    {        Update(2*n,node[n].l,mid,node[n].lazy);        Update(2*n+1,mid+1,node[n].r,node[n].lazy);        node[n].lazy = 0;    }}void Build (int u,int left,int right){    node[u].l = left,node[u].r = right;    node[u]    if (node[u].l == node[u].r)    {        node[u].sum = A[left];        node[u].minx = A[left];         return ;    }    int mid = (node[u].l + node[u].r)>>1;    Build (L(u),left,mid);    Build (R(u),mid+1,right);    Pushup(u);}void Update(int u,int left,int right,int val){    if (left==node[u].l&&node[u].r == right)    {        node[u].sum += val * (right - left + 1);        node[u].lazy += val;        node[u].minx += val;        return ;    }    Pushdown(u);          //延时更新    int mid = (node[u].l + node[u].r)>>1;    if (right <= mid) Update(L(u),left,right,val);    else if (left > mid) Update(R(u),left,right,val);    else    {        Update(L(u),left,mid,val);        Update(R(u),mid+1,right,val);    }    Pushup(u);        //这里不需要再向上更新,因为我们是从上到下更新的}long long QuerySum(int u,int left,int right){    if (left <= node[u].l&&node[u].r <= right)        return node[u].sum;    Pushdown(u);    int mid = (node[u].l + node[u].r)>>1;    if (right <= mid) return QuerySum(L(u),left,right);    else if (left > mid) return QuerySum(R(u),left,right);    else return (QuerySum(L(u),left,mid) + QuerySum(R(u),mid+1,right));    Pushup(u);}long long QueryMin(int u,int left,int right){    if (left <= node[u].l&&node[u].r <= right)        return node[u].minx;    Pushdown(u);    int mid = (node[u].l + node[u].r)>>1;    if (right <= mid) return QueryMin(L(u),left,right);    else if (left > mid) return QueryMin(R(u),left,right);    else return min(QueryMin(L(u),left,mid) , QueryMin(R(u),mid+1,right));    Pushup(u);}int main (){     // freopen("in.txt","r",stdin);    int n,m;    int a,b,c;    char s[10];    scanf("%d%d",&n,&m);    for(int i = 1; i <= n; i ++)    {        scanf("%d",&A[i]);    }    Build(1,1,n);    for(int i = 0; i < m; i ++)    {        scanf("%s",s);        if(s[0] == 'P')        {            scanf("%d%d%d",&a,&b,&c);            Update(1,a,b,c);        }        if(s[0] == 'M')        {            scanf("%d%d",&a,&b);            printf("%lld\n",QueryMin(1,a,b));        }        if(s[0] == 'S')        {            scanf("%d%d",&a,&b);            printf("%lld\n",QuerySum(1,a,b));        }    }    return 0;}

代码:

0 0
原创粉丝点击