POJ 4047 Garden 解题报告

题目


题意:

有n个连续的一维上的点,每个点有一个美丽值。

每次有三种操作:

1、将x点的美丽值改为y。

2、将x、y交换

3、查询[x y]间,连续k个点的美丽值总和的最大值。


解法:

线段树,叶子i表示[i i+k]美丽值总和,然后每个点维护一个区间最大值。

修改时区间修改,将包含x的所有叶子都修改(用lazy标记),查询时输出区间最大值。

Time:344ms
Memory:5348KB
Length:2732B
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#define DBLE 1e-8
#define PI 3.1415926535898
#define INF 1000000000
#define MAXN (1<<18)
#define MP(x,y) (make_pair((x),(y)))
#define FI first
#define SE second
using namespace std;
int sum[MAXN],node[MAXN];
int tree[MAXN*2],lazy[MAXN*2];
int n,m,k;
void build(int pos,int l,int r)
{
    tree[pos]=-INF;
    if(l==r)
    {
        tree[pos]=sum[l+k-1]-sum[l-1];
        return ;
    }
    int mid=(l+r)/2;
    build(pos*2,l,mid);
    build(pos*2+1,mid+1,r);
    tree[pos]=max(tree[pos*2],tree[pos*2+1]);
}
void cha(int pos,int l,int r,int dl,int dr,int num)
{
    if(lazy[pos])
    {
        tree[pos]+=lazy[pos];
        if(l!=r)
        {
            lazy[pos*2]+=lazy[pos];
            lazy[pos*2+1]+=lazy[pos];
        }
        lazy[pos]=0;
    }
    if(dl<=l&&dr>=r)
    {
        if(l!=r)
        {
            lazy[pos*2]+=num;
            lazy[pos*2+1]+=num;
        }
        tree[pos]+=num;
        return ;
    }
    else    if(dr<l||dl>r)
        return ;
    int mid=(l+r)/2;
    cha(pos*2,l,mid,dl,dr,num);
    cha(pos*2+1,mid+1,r,dl,dr,num);
    tree[pos]=max(tree[pos*2],tree[pos*2+1]);
}
int mfind(int pos,int l,int r,int dl,int dr)
{
    int ans;
    if(lazy[pos])
    {
        tree[pos]+=lazy[pos];
        if(l!=r)
        {
            lazy[pos*2]+=lazy[pos];
            lazy[pos*2+1]+=lazy[pos];
        }
        lazy[pos]=0;
    }
    if(dl<=l&&dr>=r)
        return tree[pos];
    else    if(dr<l||dl>r)
        return -INF;
    int mid=(l+r)/2;
    ans=max(mfind(pos*2,l,mid,dl,dr),mfind(pos*2+1,mid+1,r,dl,dr));
    tree[pos]=max(tree[pos*2],tree[pos*2+1]);
    return ans;
}
int main()
{
    //freopen("J:\\MyDocument\\Code\\input.txt","r",stdin);
    int ncase,a,b,c;
    scanf("%d",&ncase);
    while(ncase--)
    {
        memset(lazy,0,sizeof(lazy));
        scanf("%d%d%d",&n,&m,&k);
        sum[0]=0;
        for(int i=1;i<=n;++i)
            scanf("%d",&node[i]),sum[i]=sum[i-1]+node[i];
        build(1,1,n-k+1);
        n=n-k+1;
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)
            {
                cha(1,1,n,max(b-k+1,1),min(b,n),node[c]-node[b]);
                swap(b,c);
                cha(1,1,n,max(b-k+1,1),min(b,n),node[c]-node[b]);
                swap(node[b],node[c]);
            }
            else    if(a==0)
            {
                cha(1,1,n,max(b-k+1,1),min(b,n),c-node[b]);
                node[b]=c;
            }
            else    printf("%d\n",mfind(1,1,n,b,c-k+1));
        }
    }
    return 0;
}


你可能感兴趣的:(POJ 4047 Garden 解题报告)