HDU 4027 Can you answer these queries 線段樹

來源:互聯網
上載者:User

題意:在一場戰役中,敵方有一排編號為1至n的戰艦。你的指揮官有兩種命令: 1.下令使用秘密武器攻擊敵方戰艦,每次攻擊使得敵方一定範圍的所有戰艦的耐久度降低至原來的平方根(若平方根不為整數,那麼捨去後面的小數部分)。2.詢問敵方一定範圍內的所有戰艦的耐久度之和。
題解:網賽卡在這道題上了。淚流滿面呀。稍不注意就TL, 逾時的代碼也貼出來,吸取教訓···。
640ms,把down函數內聯可以到500幾吧。

#include <cmath>#include <iostream>using namespace std;#define lint __int64#define L(u) (u<<1)#define R(u) (u<<1|1)#define max(a,b) (a>b?a:b)#define N  200005lint sum[N][10];lint array[N][10];lint maxNum, maxSqrt;struct Node{    int l, r, v, add, flag; /* flag == 1說明節點內部所有點的v值一樣,即受到攻擊次數一樣 */} node[N*4];void build ( int u, int l, int r ){    node[u].l = l;    node[u].r = r;    node[u].v = node[u].add = 0;node[u].flag = 1;    if ( l == r ) return;    lint mid = ( l + r ) >> 1;    build ( L(u), l, mid );    build ( R(u), mid+1, r );}void down ( int u ){if ( node[u].add != 0 ){node[L(u)].v += node[u].add;node[R(u)].v += node[u].add;node[L(u)].add += node[u].add;node[R(u)].add += node[u].add;node[u].add = 0;}node[u].flag = -1; /* 每次向下更新時,因為節點內部的 v 不可能全部一樣了,所以需要把 flag 置為 -1 */}void update ( int u, int l, int r ){    if ( (l == node[u].l && node[u].r == r) || node[u].l == node[u].r  )    {node[u].v++;node[u].add++;        return;    }down(u);    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        update ( L(u), l, r );    else if ( l > mid )        update ( R(u), l, r );    else    {        update ( L(u), l, mid );        update ( R(u), mid+1, r );    }}lint query ( int u, int l, int r ){    if ( l == node[u].l && node[u].r == r )    {if ( node[u].v >= maxSqrt )node[u].v = maxSqrt;if ( node[u].v == maxSqrt || node[u].l == node[u].r || node[u].flag == 1 )return sum[r][node[u].v] - sum[l-1][node[u].v];down(u);        return query( L(u), l, (l+r)/2 ) + query( R(u), (l+r)/2+1, r );    }down(u);    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        return query ( L(u), l, r );    else if ( l > mid )        return query ( R(u), l, r );    else        return query ( L(u), l, mid ) + query ( R(u), mid+1, r );}int main(){    int n, m;    int t, x, y, i, j;    int test = 0;    while ( scanf("%d",&n) != EOF )    {maxNum = 0;        for ( i = 1; i <= n; i++ )        {            scanf("%I64d", &array[i][0]);if ( array[i][0] > maxNum )maxNum = array[i][0];}maxSqrt = 0;while ( maxNum > 1 ){maxNum = (lint) sqrt(maxNum+0.0);maxSqrt++;}for ( i = 0; i < 10; i++ )            sum[0][i] = 0;for ( i = 1; i <= n; i++ ){            for ( j = 0; j <= maxSqrt; j++ ){if ( j == 0 )sum[i][0] = sum[i-1][0] + array[i][0];else{                    array[i][j] = (lint) sqrt(array[i][j-1]+0.0);                    sum[i][j] = sum[i-1][j] + array[i][j];}            }        }        build ( 1, 1, n );        scanf("%d",&m);        printf("Case #%d:\n", ++test);        while( m-- )        {            scanf("%d%d%d",&t,&x,&y);            if ( x > y ) swap(x,y);            if ( t == 0 )                update ( 1, x, y );            else                         printf("%I64d\n", query ( 1, x, y ));        }putchar('\n');    }    return 0;}

812ms:

#include <cmath>#include <iostream>using namespace std;#define lint __int64#define L(u) (u<<1)#define R(u) (u<<1|1)#define N  200005lint array[N];lint maxNum;int n, m, maxSqrt;struct Node{    int l, r, v, add;lint sum[8];} node[N*4];void build ( int u, int l, int r ){    node[u].l = l;    node[u].r = r;    node[u].v = 0;node[u].add = 0;    if ( l == r ){lint temp, i = 0;node[u].sum[0] = temp = array[l];if ( array[l] == 0 ){for ( i = 0; i <= maxSqrt; i++ )node[u].sum[i] = 0;return;}while ( temp > 1 ){temp = (lint) sqrt(temp+0.0);node[u].sum[++i] = temp;}while ( i <= maxSqrt )node[u].sum[++i] = 1;return;}    int mid = ( l + r ) >> 1;    build ( L(u), l, mid );    build ( R(u), mid+1, r );for ( int i = 0; i <= maxSqrt; i++ )node[u].sum[i] = node[L(u)].sum[i] + node[R(u)].sum[i];}void update ( int u, int l, int r ){    if ( l == node[u].l && node[u].r == r )    {node[u].v++;node[u].add++;        return;    }if ( node[u].add != 0 ){node[L(u)].v += node[u].add;node[R(u)].v += node[u].add;    node[L(u)].add += node[u].add;node[R(u)].add += node[u].add;node[u].add = 0;}    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        update ( L(u), l, r );    else if ( l > mid )        update ( R(u), l, r );    else    {        update ( L(u), l, mid );        update ( R(u), mid+1, r );    }}lint query ( int u, int l, int r ){    if ( l == node[u].l && node[u].r == r )    {if ( node[u].v > maxSqrt )node[u].v = maxSqrt;if ( node[u].v == maxSqrt || node[u].l == node[u].r  )            return node[u].sum[node[u].v];if ( node[u].add != 0 ){node[L(u)].v += node[u].add;node[R(u)].v += node[u].add;node[L(u)].add += node[u].add;node[R(u)].add += node[u].add;node[u].add = 0;}int mid = ( node[u].l + node[u].r ) >> 1;        return query ( L(u), l, mid ) + query ( R(u), mid+1, r );    }if ( node[u].add != 0 ){node[L(u)].v += node[u].add;node[R(u)].v += node[u].add;    node[L(u)].add += node[u].add;node[R(u)].add += node[u].add;node[u].add = 0;}    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        return query ( L(u), l, r );    else if ( l > mid )        return query ( R(u), l, r );    else        return query ( L(u), l, mid ) + query ( R(u), mid+1, r );}int main(){    int t, x, y, test = 0;    while ( scanf("%d",&n) != EOF )    {maxNum = 0;        for ( int i = 1; i <= n; i++ )        {            scanf("%I64d", &array[i]);maxNum = array[i] > maxNum ? array[i] : maxNum;}maxSqrt = 0;while ( maxNum > 1 ){maxNum = (lint) sqrt(maxNum+0.0);maxSqrt++;}        build ( 1, 1, n );        scanf("%d",&m);        printf("Case #%d:\n", ++test);        while( m-- )        {            scanf("%d%d%d",&t,&x,&y);            if ( x > y ) swap(x,y);            if ( t == 0 )                update ( 1, x, y );            else                         printf("%I64d\n", query ( 1, x, y ));        }putchar('\n');    }    return 0;}

TL代碼。與上面的代碼相比,僅僅是節點內少了一個add變數。但是這樣一來,每次向下更新時會把 v 置為 0, 那麼 node[u].v > maxSqrt這個最佳化條件就被減弱了。悲劇由此產生,唉··

#include <cmath>#include <iostream>using namespace std;#define lint __int64#define L(u) (u<<1)#define R(u) (u<<1|1)#define max(a,b) (a>b?a:b)#define N  200005lint sum[N][10];lint array[N][10];lint maxNum, maxSqrt;struct Node{    int l, r, v, flag;} node[N*4];void build ( int u, int l, int r ){    node[u].l = l;    node[u].r = r;    node[u].v = 0;node[u].flag = 1;    if ( l == r ) return;    lint mid = ( l + r ) >> 1;    build ( L(u), l, mid );    build ( R(u), mid+1, r );}void down ( int u ){if ( node[u].v != 0 ){node[L(u)].v += node[u].v;node[R(u)].v += node[u].v;node[u].v = 0;}node[u].flag = -1;}void update ( int u, int l, int r ){    if ( (l == node[u].l && node[u].r == r) || node[u].l == node[u].r  )    {node[u].v++;        return;    }down(u);    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        update ( L(u), l, r );    else if ( l > mid )        update ( R(u), l, r );    else    {        update ( L(u), l, mid );        update ( R(u), mid+1, r );    }}lint query ( int u, int l, int r ){    if ( l == node[u].l && node[u].r == r )    {if ( node[u].v >= maxSqrt )node[u].v = maxSqrt;if ( node[u].v == maxSqrt || node[u].l == node[u].r || node[u].flag == 1 )return sum[r][node[u].v] - sum[l-1][node[u].v];down(u);        return query( L(u), l, (l+r)/2 ) + query( R(u), (l+r)/2+1, r );    }down(u);    int mid = ( node[u].l + node[u].r ) >> 1;    if ( r <= mid )        return query ( L(u), l, r );    else if ( l > mid )        return query ( R(u), l, r );    else        return query ( L(u), l, mid ) + query ( R(u), mid+1, r );}int main(){    int n, m;    int t, x, y, i, j;    int test = 0;    while ( scanf("%d",&n) != EOF )    {maxNum = 0;        for ( i = 1; i <= n; i++ )        {            scanf("%I64d", &array[i][0]);if ( array[i][0] > maxNum )maxNum = array[i][0];}maxSqrt = 0;while ( maxNum > 1 ){maxNum = (lint) sqrt(maxNum+0.0);maxSqrt++;}for ( i = 0; i < 10; i++ )            sum[0][i] = 0;for ( i = 1; i <= n; i++ ){            for ( j = 0; j <= maxSqrt; j++ ){if ( j == 0 )sum[i][0] = sum[i-1][0] + array[i][0];else{                    array[i][j] = (lint) sqrt(array[i][j-1]+0.0);                    sum[i][j] = sum[i-1][j] + array[i][j];}            }        }        build ( 1, 1, n );        scanf("%d",&m);        printf("Case #%d:\n", ++test);        while( m-- )        {            scanf("%d%d%d",&t,&x,&y);            if ( x > y ) swap(x,y);            if ( t == 0 )                update ( 1, x, y );            else                         printf("%I64d\n", query ( 1, x, y ));        }putchar('\n');    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.