POJ 4047 Garden (線段樹)

來源:互聯網
上載者:User

題意:輸入N,M,K。有N個點,每個點有一個值,然後有M個操作 0 x y 表示將x的值賦為y;  1 x y 表示將x和y互換下位置(相應值也互換) ; 2 x y 表示詢問[x,y]內連續K個數和的最大值。


一開始想用每個點來建樹,發現不好維護區間內連續K個數的和的最大值。

但如果轉化一下,因為K是定值,將[x,x+k-1]區間的和看做一個點,這樣以連續K個數和作為點,共有N-K+1的點建樹。 變成了求線段樹區間最值問題。

於是單點更新,轉化為了區間更新: 修改了點x處的值,則產生的影響區間為 【max(1,x-k+1),min(n-k+1,x) 】。


#include <iostream>#include <algorithm>#include <cmath>#include<functional>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <queue>#include <stack>#include <climits>//形如INT_MAX一類的#define MAX 200050#define INF 0x7FFFFFFF#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5using namespace std;inline void RD(int &ret) {    char c;    int flag = 1 ;    do {        c = getchar();        if(c == '-')flag = -1 ;    } while(c < '0' || c > '9') ;    ret = c - '0';    while((c=getchar()) >= '0' && c <= '9')        ret = ret * 10 + ( c - '0' );    ret *= flag ;}void OT(int a) {    if(a < 0) {        putchar('-');        a = -a;    }    if(a >= 10)OT(a / 10);    putchar(a % 10 + '0');}int n,m,k;struct node {    int l,r,mid;    int v,add;}tr[MAX * 4];int a[MAX],va[MAX];void init() {    memset(va,0,sizeof(va));}void up(int x) {    tr[x].v = max(tr[L(x)].v, tr[R(x)].v);}void build(int l,int r,int x) {    tr[x].l = l;    tr[x].r = r;    tr[x].mid = (l + r) >> 1;    tr[x].add = 0;    if(l == r) {        tr[x].v = va[l];        return ;    }    build(l,tr[x].mid,L(x));    build(tr[x].mid+1,r,R(x));    up(x);}void down(int x) {    if(tr[x].add != 0) {        tr[L(x)].add += tr[x].add;        tr[R(x)].add += tr[x].add;        tr[L(x)].v += tr[x].add;        tr[R(x)].v += tr[x].add;        tr[x].add = 0;    }}void update(int l,int r,int x,int val) {    if(l <= tr[x].l && r >= tr[x].r) {        tr[x].add += val;        tr[x].v += val;        return ;    }    down(x);    int mid = tr[x].mid;    if(l <= mid) update(l,r,L(x),val);    if(r > mid) update(l,r,R(x),val);    up(x);}int query(int l,int r,int x) {    if(l <= tr[x].l && r >= tr[x].r) {        return tr[x].v;    }    down(x);    int mid = tr[x].mid;    if(r <= mid) return query(l,r,L(x));    else if(l > mid) return query(l,r,R(x));    else {        return max(query(l,mid,L(x)), query(mid+1,r,R(x)));    }}void test() {    int size = n - k + 1;    for(int i=1; i<=3 * size; i++) {        printf("%d %d %d %d\n",tr[i].l,tr[i].r,tr[i].v,tr[i].add);    }}int main() {    int T;    cin >> T;    while(T --) {        init();        scanf("%d%d%d",&n,&m,&k);        for(int i=1; i<=n; i++) RD(a[i]);        for(int i=1; i<=k; i++) va[1] += a[i];        for(int i=k+1; i<=n; i++) {            va[i - k + 1] = va[i - k] - a[i - k] + a[i];        }        build(1,n-k+1,1);        int b,c,d;        for(int i=0; i<m; i++) {            RD(b);RD(c);RD(d);            if(b == 0) {                int val = d - a[c];                update(max(1,c-k+1),min(n-k+1,c),1,val);                a[c] = d;            }            if(b == 1) {                if(c == d || a[c] == a[d]) continue;                int x1 = a[c] - a[d];                int x2 = a[d] - a[c];                update(max(1,c-k+1),min(n-k+1,c),1,x2);                update(max(1,d-k+1),min(n-k+1,d),1,x1);                swap(a[c],a[d]);            }            if(b == 2) {                OT(query(c,d-k+1,1));                puts("");            }        }    }    return 0;}/*15 7 3-1 2 -4 6 12 1 52 1 31 2 12 1 52 1 40 2 42 1 5*/


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.