算法训练 操作格子

                                                                                          算法训练 操作格子  
时间限制:1.0s   内存限制:256.0MB
      
问题描述

有n个格子,从左到右放成一排,编号为1-n。

共有m次操作,有3种操作类型:

1.修改一个格子的权值,

2.求连续一段格子权值和,

3.求连续一段格子的最大值。

对于每个2、3操作输出你所求出的结果。

输入格式

第一行2个整数n,m。

接下来一行n个整数表示n个格子的初始权值。

接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。

输出格式

有若干行,行数等于p=2或3的操作总数。

每行1个整数,对应了每个p=2或3操作的结果。

样例输入
4 3
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
数据规模与约定

对于20%的数据n <= 100,m <= 200。

对于50%的数据n <= 5000,m <= 5000。

对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。

#include<iostream>
#include<cstdio>
#define maxn 500004
struct  node
{
    int left,right;
    int num;
}tree[3*maxn];
int  maxv[2*maxn];
int out=0;
int max(int x,int y)
{
    if(x>y)
       return x;
    else
       return y;
}
void build(int left,int right,int i)
{
    tree[i].left=left;
    tree[i].right=right;
    tree[i].num=0;
    if(tree[i].left==tree[i].right)
         return ;
    int mid=(left+right)/2;
    build(left,mid,2*i);
    build(mid+1,right,2*i+1);
}
void insert(int id,int i,int j)
{
      if(tree[id].left==i&&tree[id].right==i)
               {
                   tree[id].num=j;
                   maxv[id]=j;
               }
      if(tree[id].left==tree[id].right)
                 return ;
    if(i>tree[id].right)
        return;
    if(i<tree[id].left)
            return;
     int mid=(tree[id].left+tree[id].right)/2;
     if(i<=mid)
         insert(id*2,i,j);
     else
         insert(id*2+1,i,j);
    tree[id].num=tree[2*id].num+tree[2*id+1].num;
    maxv[id]=max(maxv[id*2],maxv[id*2+1]);
}
void sum(int id,int i,int j)
{
    int mid=(tree[id].left+tree[id].right)/2;
    if(tree[id].left==i&&tree[id].right==j)
     {
         out+=tree[id].num;
         return ;
     }
     if(j<=mid)
       sum(id*2,i,j);
     else if(i>mid)
         sum(id*2+1,i,j);
     else
     {
        sum(id*2,i,mid);
        sum(id*2+1,mid+1,j);
     }
}
int query(int id,int l,int r)
{
      int mid=(tree[id].left+tree[id].right)/2;
      int ans=0;

      if(l==tree[id].left&&r==tree[id].right)
             {
               
                   return maxv[id];
             }
      if(r<=mid)
         ans=max(ans,query(id*2,l,r));
     else if(l>mid)
          ans=max(ans,query(id*2+1,l,r));
     else
         {
              ans=max(ans,query(id*2,l,mid));
              ans=max(ans,query(id*2+1,mid+1,r));
         }
     return ans;
}
int main()
{
    int i,p,x,y;
    int n,m,u;
   while(~ scanf("%d%d",&n,&m))
   {
       build(1,n,1);
     for(i=1;i<=n;i++)
    {
        scanf("%d",&u);
        insert(1,i,u);
    }
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&p,&x,&y);
          if(p==1)
             insert(1,x,y);
         if(p==2)
            {
                  sum(1,x,y);
                  printf("%d\n",out);
                  out=0;
            }
         if(p==3)
         {
           printf("%d\n",query(1,x,y));
         }
     }
   }
     return 0;
}

 

posted @ 2015-03-20 17:08  疯狂的癫子  阅读(287)  评论(0编辑  收藏  举报