POJ 4047Garden

金华邀请赛题目D

线段树

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct node
{   int l,r;
    int mx;
    int re;
};
node lt[800000];
int n,Max;
int a[200003],b[200003];
void built(int l,int r,int k)//建树
{   lt[k].l=l;
    lt[k].r=r;
    lt[k].re=0;
    if(l==r)
    {
        lt[k].mx=b[l];
        return ;
    }
    int m=(l+r)>>1;
    int t=k<<1;
    built(l,m,t);
    built(m+1,r,t|1);
    lt[k].mx=lt[t].mx>lt[t|1].mx?lt[t].mx:lt[t|1].mx;
}

void down(int k) //这个很重要,要将上层数据下压
{
  if(lt[k].re==0) return ;
  lt[k].mx+=lt[k].re;
  if(lt[k].l!=lt[k].r)
  {
   lt[k<<1].re+=lt[k].re;
   lt[k<<1|1].re+=lt[k].re;
  }
   lt[k].re=0;
}
int va;
void up(int x,int y,int k)  //更新
{
   down(k);
   if(x==lt[k].l&&y==lt[k].r)//成段更新
   {
      lt[k].re+=va;
       down(k);
       return ;
   }
   int m=(lt[k].l+lt[k].r)>>1;
   int t=k<<1;
   if(x<=m&&y>m)
   {
       up(x,m,t);
       up(m+1,y,t|1);
   }
   else if(x>m)
        { up(x,y,t|1);down(t);}
        else {up(x,y,t);down(t|1);}
   lt[k].mx=lt[t].mx>lt[t|1].mx?lt[t].mx:lt[t|1].mx;
}

int _max(int x,int y,int k)//求最大值
{
    down(k);                //下压
     if(lt[k].l==x&&lt[k].r==y)
     {
         return lt[k].mx;
     }
   int m=(lt[k].l+lt[k].r)>>1;
   if(x<=m&&y>m)
   {
       return max(_max(x,m,k<<1),_max(m+1,y,k<<1|1));
   }
   else if(x>m)
        {return  _max(x,y,k<<1|1);}
        else {return _max(x,y,k<<1);}
}
int main()
{
    freopen("in.txt","r",stdin);
    freopen("out1.txt","w",stdout);
    int t,m,sum;
    int i,j;
    int q,x,y,t_x,t_y,k;
    scanf("%d",&t);
    while(t--)
    {    sum=0;
       scanf("%d%d%d",&n,&m,&k);
       for(i=1;i<=k;sum+=a[i],i++)
         scanf("%d",&a[i]);
         b[k]=sum;
       for(j=1;i<=n;sum=sum-a[j]+a[i],b[i]=sum,j++,i++)
         scanf("%d",&a[i]);

      built(k,n,1);
      for(i=0;i<m;i++)
      {
          scanf("%d%d%d",&q,&x,&y);
          switch(q)
          {
              case 0:
              va=y-a[x];a[x]=y;t_x=x;t_y=x+k-1;
              if(t_x<k) t_x=k;if(t_y>n) t_y=n;
              up(t_x,t_y,1);break;

              case 1:
              va=a[y]-a[x];t_x=x;t_y=x+k-1;
              if(t_x<k) t_x=k;if(t_y>n) t_y=n;
              up(t_x,t_y,1);

              va=a[x]-a[y];t_x=y;t_y=y+k-1;
              if(t_x<k) t_x=k; if(t_y>n) t_y=n;
              up(t_x,t_y,1);swap(a[x],a[y]);
              break;
              case 2:printf("%d\n",_max(x+k-1,y,1));break;
          }
      }
    }
    return 0;
}

posted on 2012-05-20 08:53  江财小子  阅读(185)  评论(0编辑  收藏  举报