[HDU 4267](长春1001) 正式可以手写线段树了

来源:互联网 发布:java中求字符串的长度 编辑:程序博客网 时间:2024/04/28 03:31

跟孟神混,向着金牌!

方法一: 开55棵线段树

方法二: 线段树55个Node。

Attation:

1、线段树传Struct TLE

2、开55*50000*2 MLE

3、多点更新单点求值不用PushUp

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>using namespace std;#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int N = 50001;int zhuzhu[20][20];struct Meng{    int v[55],add;    void clear(){        memset(v,0,sizeof(v));        add=0;    }    Meng operator + (const Meng & A) const{        Meng ret;        ret.add=0;        for (int i = 0 ; i < 55 ; ++ i ){            ret.v[i] = v[i] + A.v[i];            ret.add += v[i] + A.v[i];        }        return ret;    }    void output(){        for (int i = 0 ; i < 55 ; ++ i)            printf(" %d" , v[i]);        printf("\n");    }}tree[ N << 2 ];int add[ N << 2 ];void PushUp(int rt){    tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];}void PushDown(int rt){    if (add[rt]){        tree[rt << 1] = tree[rt << 1] + tree[rt];        tree[rt << 1 | 1] = tree[rt << 1 | 1] + tree[rt];        add[rt << 1] = add[rt << 1] + add[rt];        add[rt << 1 | 1] = add[rt << 1 | 1] + add[rt];        add[rt]=0;        tree[rt].clear();    }}void build(int l , int r , int rt ){    add[rt]=0;    if (l == r){        tree[rt].clear();        return;    }    int m = (l + r) >> 1;    build(lson);    build(rson);    PushUp(rt);}void update(int L , int R , int k , int c , int l, int r, int rt){    if (L <= l && r <= R){        tree[rt].v[ zhuzhu[k][L%k] ] += c;        tree[rt].add += c;        add[rt]+= c;        return;    }    PushDown(rt);    int m = (l + r) >> 1;    if (L <= m) update(L , R , k , c , lson);    if (m < R) update(L , R , k , c , rson);    //PushUp(rt);}int query(int p , int l , int r ,int rt){    if (l == r) {        int zhu = 0 , res = 0;        for (int i = 1; i <= 10 ; ++ i)            res += tree[rt].v[ zhuzhu[i][p%i] ];        return res;    }    PushDown(rt);    int m = (l + r) >> 1;    if (p <= m) return query(p , lson);    return query(p , rson);}int a[N] , n;void solve(){    for (int i = 1 ; i <= n ; ++ i){        scanf("%d",&a[i]);    }    build(1 , n , 1);    int m;    scanf("%d", &m);    while (m--){        int op;        scanf("%d", &op);        if (op==2){            int x;            scanf("%d", &x);            //res.output();            int ans = a[x] + query(x,1,n,1);            printf("%d\n",ans);        }        else{            int a,b,k,c;            scanf("%d%d%d%d",&a,&b,&k,&c);            update(a,b,k,c,1,n,1);        }    }}void init(){    int zhu=0;    for (int i = 1 ; i <= 10 ; ++ i)        for (int j = 0 ; j < i ;  ++j ){            zhuzhu[i][j]=zhu++;        }}int main(){    init();    while (~scanf("%d",&n)) solve();}




原创粉丝点击