1. 程式人生 > >樹狀陣列(區間修改,單點查詢)

樹狀陣列(區間修改,單點查詢)

這裡介紹樹狀陣列+差分思想,算是對下面大神的補充吧。

何為差分現在我們有一個從小到大的數列a[]

a{1,3,6,8,9};

然後還有一個差分陣列b[]

b{1,2,3,2,1}

相信某些小夥伴已經看出端倪了..這裡b[i]=a[i]-a[i-1],我令a[0]=0,故b[1]=a[1]。

擁有了b陣列,我們就可以很簡單的求出bit[]中任意一個數,只需bit[i]=sigma(k=1to i) b[k](這個很好推吧..)

我覺得現在該有人說我zz了..何必不直接查詢a[i]而是找這麼麻煩一個方法..這裡我們轉回正題!

別忘了,題目要我們進行區間修改..我們知道,樹狀陣列對於單點值的修改十分方便(不懂的去看樹狀陣列

1),對於區間的修改就比較尷尬..

而我們又不想敲死長的線段樹..怎麼辦呢,這時候差分就顯出優勢還是上面的a[]和b[],現在我們使區間[2,4]的所有數均+2

a[]/b[]變為

a{1,5,8,10,9}

b{1,4,3,2,-1}

事實上,這裡只有b[2]和b[5]發生了變化,因為區間內元素均增加了同一個值,所以b[3],b[4]是不會變化的。

這裡我們就有了第二個式子:對於區間[x,y]的修改(增加值為d)在b陣列內引起變化的只有 b[x]+=d,b[y+1]-=d。(這個也很好推的..)

還有程式碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define P pair<int,int>
#define pi acos(-1)
inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
int n,a[100008];
int sum(int x)
{
    int s=0;
    while(x>0)
    {
        s+=a[x];
        x-=x&-x;
    }
    return s;
}
void add(int x,int y)
{
    while(x<=n)
    {
        a[x]+=y;
        x+=x&-x;
    }
    return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n&&n)
    {
        REW(a,0);
        int e=n;
        while(e--)
        {
            int q,w;
            q=read(),w=read();
            add(q,1);
            add(w+1,-1);
        }
        for(int i=1;i<n;i++)
        {
            cout<<sum(i)<<" ";
        }
        cout<<sum(n)<<endl;
    }
    return 0;
}

相關推薦

陣列區間修改查詢

這裡介紹樹狀陣列+差分思想,算是對下面大神的補充吧。 何為差分現在我們有一個從小到大的數列a[] a{1,3,6,8,9}; 然後還有一個差分陣列b[] b{1,2,3,2,1} 相信某些小夥伴已經看

二維陣列區間修改查詢

好像不管是幾維都和一維原理差不多,多了一個維度也就多了一層迴圈而已(QAQ) #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath&g

關於陣列區間修改查詢

寫在前面 之前一直不知道樹狀陣列可以支援區間修改,所以寫一篇部落格記錄一下。 首先給個小栗子: 如下圖: 利用差分的思路,就得到下圖: 那麼如果我們要求將2~4的所有元素+2呢?我們就可以得到下圖: 可以發現,差分的第二項和第五項一個加了2,一個減了2

Matrix 二維陣列 區間修改查詢

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i,

陣列更新和區間更新二維陣列poj2155區間更新查詢已加入區間修改區間查詢

普通的樹狀陣列C[i]=a[i]+a[i-1]+...a[i-2^k+1]+...+a[1]; 但是所有樹狀陣列都是向上更新,向下求和。 1)、單點增減+區間求和 思路:C[x]表示該點的元素:sum(x)=C[1]+C[2]+……C[x] [cpp] view p

Color the ball 陣列區間更新查詢

N個氣球排成一排,從左到右依次編號為1,2,3....N.每次給定2個整數a b(a <= b),lele便為騎上他的“小飛鴿"牌電動車從氣球a開始到氣球b依次給每個氣球塗一次顏色。但是N次以後lele已經忘記了第I個氣球已經塗過幾次顏色了,你能幫他算出每個氣球被塗過幾次顏色嗎? Inpu

陣列區間修改查詢洛谷:陣列2

模版和單點修改區間查詢差不多 樹狀陣列(單點修改區間查詢) https://blog.csdn.net/johnwayne0317/article/details/84927585 然後用到了差分陣列 https://blog.csdn.net/johnwayne0317/a

陣列專題 更新、區間求和 + 區間更新、查詢 + 區間更新、區間求和差分思想)

                                                                                            樹狀陣列專題 一直感覺樹狀陣列用處比較小而且侷限、因為最基本的用法就是單點更新和區間求和、

線段大模板區間更新更新查詢區間最值等等

#include <bits/stdc++.h> #define MAXN 100010 #define inf 0x3f3f3f3f using namespace std; struct node{ int l,r;//區間[l,r

數組基本模版(區間更新查詢)

pre color pan style 列數 strong syn def spa 題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數數加上x 2.求出某一個數的和 輸入輸出格式 輸入格式: 第一行包含兩個整數N、M,分別表示該數列數字的個數和操作

數組的區間修改查詢區間查詢

pri 區間 stream 個數 普通 sca ace 一個數 n)     如何將普通樹狀數組升級   普通的單點修改單點查詢就不講了,從區間修改和單點查詢講起。   原來的值存在a[]裏面,多建立個數組c1[],註意:c1[i]=a[i]-a[i-1]。   那麽求a[

數組區間修改區間更新:差分數組的運用

容易 div 前綴和 根據 www 數組 一個數 log 一個 樹狀數組最原始的作用就是求前綴和,可以實現單點修改和區間查詢。 但是假設現在有: 1.區間修改,單點查詢 2.區間修改,區間查詢 但是又不想敲線段樹怎麽辦? 就用樹狀數組嘍。 假設現在有一個原數組a

關於數組的區間修改查詢

地址 src 區間修改 r+ 寫在前面 mar article .net 操作 寫在前面 之前一直不知道樹狀數組可以支持區間修改,所以寫一篇博客記錄一下。 首先給個小栗子: 如下圖: 利用差分的思路,就得到下圖: 那麽如果我們要求將2~4的所有元素+2呢?我們就可以得到

陣列hdu-4325hdu-1166pat-1057

1、hdu-4325 題意:插花,要麼給出插花的範圍,要麼查詢某個點的花的個數。 思路:通過更新,每次更新區間S到T的數值,表插入花(這一點一開始沒想到), 要麼查詢某個點的花的數目。 (與以往單純的區間查詢和單點修改的區間和不太相同)。   2、hdu-1166 典型的單點查詢,區間

【codevs1082】【陣列區間修改 區間查詢

題目描述 Description 給你N個數,有兩種操作: 1:給區間[a,b]的所有數增加X 2:詢問區間[a,b]的數的和。 輸入描述 Input Descri

陣列區間更新差分思想

已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數數加上x 2.求出某一個數的和 題: 第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。 第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。 接下來M行每行包含2或

陣列區間修改區間查詢模板

#include <iostream> using namespace std; #define lowbit(x) ((x) & (-(x))) long long arrC1[200010], arrC2[200010]; long long

陣列區間修改

參考部落格:https://blog.csdn.net/fsahfgsadhsakndas/article/details/52650026樹狀陣列的最基本的操作單點修改,以及區間求和單點修改:void add(int pos,int num) { while(pos

區間修改查詢

Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29305 &nbs

陣列總結——詳解/區間查詢 /區間修改 逆序對

2017-06-13 17:24 64人閱讀 評論(0)收藏舉報 1、概述   樹狀陣列(binary indexed tree),是一種設計新穎的陣列結構,它能夠高效地獲取陣列中連續n個數的和。概括說,樹狀陣列通常用於解決以下問題:陣列{a}中的元素可能不斷地被