POJ3468

 摘要:

節點裏需要記錄區間的和,區間的增量。以保證Insert和Calculate都是log(n)的,話說還不是很懂,看別人的代碼過的。。

#include <iostream>
#include <stdio.h>
using namespace std;

const int size = 100000;

typedef struct  Node{
    int left;
    int right;
    long long sum;
    long long mod;
    Node * left_child;
    Node * right_child;
    void Construct(int, int);
    void Insert(int, int, int);
    long long Calculate(int, int);
}Node;

Node sTree[size * 3];
Node *root = &sTree[0];
int len = 1;
int input[size+1] = {0};

void Node::Construct(int l, int r)
{
    left = l;
    right = r;
    sum = 0;   
    mod = 0;

    if( l == r ){
        sum = input[l];
        left_child = right_child = NULL;
        return;
    }
   
    left_child = &sTree[len++];
    right_child = &sTree[len++];

    int mid = (left + right) >> 1;
    left_child->Construct(l, mid);
    right_child->Construct(mid+1, r);       

    sum = left_child->sum + right_child->sum;
}

void Node::Insert(int l, int r, int value)
{
    //cout << "insert:" << left << "," << right << "/t" << l << "," << r << endl;
    if( l==left && r==right){
        mod += value;
        return;
    }
   
    sum += ( r - l + 1) * value;
   
    int mid = (left + right) >> 1;
    if( l > mid ){
        right_child->Insert(l, r, value);
        return;
    }
    if( r <= mid ){
        left_child->Insert(l, r, value);
        return;
    }
   
    left_child->Insert(l, mid, value);
    right_child->Insert(mid+1, r, value);
}

long long Node::Calculate(int l, int r)
{
    //cout << "right calculate:" << left << "," << right << "/t" << l << "," << r << endl;
    if( left==l && right==r){
        return sum + (right-left+1) * mod;   
    }
   
    if( mod != 0 ){
        left_child->mod += mod;
        right_child->mod += mod;
        sum += (right-left+1)*mod;
        mod = 0;       
    }
   
    int mid = (left + right) >> 1;
    //cout << mid << endl;   
    if( l > mid ){
        return right_child->Calculate(l, r);   
    }
    if( r <= mid){
        return left_child->Calculate(l, r);
    }   
   
    return left_child->Calculate(l, mid) + right_child->Calculate(mid+1, r);
}

int main()
{
    int N, Q;
    scanf("%d%d", &N, &Q);
   
    for(int i=1; i<=N; i++){
        scanf("%d", &input[i]);
    }

    len = 1;
    root->Construct(1, N);   
   
    getchar();
    for(int i=1; i<=Q; i++){   
        char ch = getchar();
        int left, right, value;
        scanf("%d%d", &left, &right);   
        if(ch == 'Q'){
            //cout << "Calculate:" << left << "," << right << endl;
            printf("%lld/n", root->Calculate(left, right));        
        }else{
            scanf("%d", &value);
            //cout << "Insert:" << left << "," << right << "," << value << endl;
            root->Insert(left, right, value);
        }
        getchar();
    }

    return 0;
}

發佈了63 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章