POJ-4047-线段树

来源:互联网 发布:linux 重启防火墙 编辑:程序博客网 时间:2024/05/22 04:48

#include <iostream>#include <cstdio>#include <cmath>#include <string>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int maxn = 200009;int n, nn, m, k; int a[maxn], b[maxn];struct tree{    int l, r, v, lazy, mid;}t[maxn*4];int build(int l, int r, int k){    t[k].l = l;    t[k].r = r;    int mid = (l+r)/2;    t[k].mid = mid;    t[k].lazy = 0;    if(l==r)    {        t[k].v = b[l];        return b[l];    }    return t[k].v = max( build(l, mid, k*2), build(mid+1, r, k*2+1) );}void down(int k){    if(t[k].l == t[k].r) return;    t[k*2].v += t[k].lazy;    t[k*2].lazy += t[k].lazy;    t[k*2+1].v += t[k].lazy;    t[k*2+1].lazy += t[k].lazy;    t[k].lazy = 0;}void updata(int l, int r, int v, int k){    if(t[k].l==l && t[k].r==r)    {        t[k].v += v;        t[k].lazy += v;        return;    }    if(t[k].lazy) down(k);    if(r<=t[k].mid) updata(l, r, v, k*2);    else if(l>t[k].mid) updata(l, r, v, k*2+1);    else    {        updata(l, t[k].mid, v, k*2);        updata(t[k].mid+1, r, v, k*2+1);    }    t[k].v = max(t[k*2].v, t[k*2+1].v);}int q(int l, int r, int k){    if( t[k].l==l && t[k].r==r ) return t[k].v;    if( t[k].lazy ) down(k);    if( r<=t[k].mid ) return q(l, r, k*2);    else if( l>t[k].mid ) return q(l, r, k*2+1);    else    {        return max( q(l, t[k].mid, k*2), t[k].lazy + q(t[k].mid+1, r, k*2+1) );    }}int main(){    int i, j, tt, p, x, y;    scanf("%d", &tt);    while(tt--)    {        scanf("%d%d%d", &n, &m, &k);        nn = n-k+1;        b[1] = 0;        for(i=1; i<=k; i++)        {            scanf("%d", &a[i]);            b[1] += a[i];        }        for(i=k+1; i<=n; i++)        {            scanf("%d", &a[i]);            b[i-k+1] = b[i-k] + a[i] - a[i-k];        }        build(1, nn, 1);        while(m--)        {            scanf("%d%d%d", &p, &x, &y);            if(p==0)            {                if( y==a[x] ) continue;                updata( max(1, x-k+1), min(x, nn), y-a[x], 1 );                a[x] = y;            }            else if(p==1)            {                if( a[x]==a[y] ) continue;                updata( max(1, x-k+1), min(x, nn), a[y]-a[x], 1 );                updata( max(1, y-k+1), min(y, nn), a[x]-a[y], 1 );                swap( a[x], a[y] );            }            else            {                printf("%d\n", q(x, y-k+1, 1));            }        }    }return 0;}

把 n 个数, 变成 n-k+1 个和。

变成就区间最值问题。