1. 程式人生 > >BZOJ3155/LNSYOJ96 preprefix【樹狀陣列x2】【做題報告】

BZOJ3155/LNSYOJ96 preprefix【樹狀陣列x2】【做題報告】

這道題是樹狀陣列+數學題,然而我數學並不好

題目描述

對於一個長度為nn的序列a1,a2,a3ana1,a2,a3……an,其字首和(Prefix Sum)SiSi為前ii個元素的和,即k=1iai∑k=1iai。而字首和的字首和(Preprefix Sum)就是把字首和序列S1,S2,S3SnS1,S2,S3……Sn作為原序列,再求一次字首和。記再次求得的字首和序列的第ii位為SSiSSi。 現在給定一個長度為

n">nn的序列a1,a2,a3ana1,a2,a3……an,有兩種操作:

Modify i x

將的值改為;

Query i

詢問SSiSSi的值。

請編寫一個程式來實現這兩種操作。

 

輸入格式

第一行有兩個整數nn和mm,分別表示序列長度和操作個數。 接下來的一行有nn個整數,即給定的序列a1,a2,a3ana1,a2,a3……an。 接下來有mm行,每行對應一個操作,格式見題目描述。

輸出格式

對於每個詢問操作,輸出一行,表示所詢問的

SSi">SSiSSi的值。

樣例一

input

5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5

output

35
32

樣例解釋

進行了修改操作之後,序列變為{1,2,3,4,5}{1,2,3,4,5},對應的字首和序列為{1,3,5,9,14}{1,3,5,9,14},故SS5=32SS5=32。

限制與約定

對於30%的資料,1n,m1001≤n,m≤100

對於70%的資料,

n,m≤1000">1n,m10001≤n,m≤1000

對於100%的資料,1n,m100000,0ai1000001≤n,m≤100000,且在任意時刻都有0≤ai≤100000

時間限制1s1s

空間限制256MB

首先這道題一看就是個樹狀陣列,別問我怎麼看出來的

然後便是開心的推結論時間

num: a1 ,a2 ,a3 ,a4

prefix: a1 ,a1+a2, a1+a2+a3

i*prefix: a1 ,2*a1+2*a2 ,3*a1+3*a2+3*a3(2)

preprefix: a1 ,2*a1+a2 ,3*a1+2*a2+a3(1)

(2)-(1): 0*a1 ,0*a1+a2 ,0*a1+a2+2*a3(3)

我們要求的就是(1)=(2)-(3);

(2)很明顯是字首和,用一個樹狀陣列就能處理,

(3)很明顯是(i-1)*ai的字首和,再用一個樹狀陣列維護

還有一點,就是要開longlong!!要開longlong!!要開longlong!!

不開longlong見祖宗,多年OI一場空

然後就A了

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define lowbit(a) a&(-a)
 5 using namespace std;
 6 typedef long long ll;
 7 ll n,m,x,y;
 8 ll tree1[101111],tree2[101111],num[101111];
 9 char opt[10];
10 void add(ll pos,ll val,ll op)
11 {
12     switch(op)
13     {
14         case 1:
15             for(int i=pos;i<=n;i+=lowbit(i))
16                 tree1[i]+=val;
17             break;
18         case 2:
19             for(int i=pos;i<=n;i+=lowbit(i))
20                 tree2[i]+=val;
21             break;
22     }
23     
24 }
25 ll ask(ll pos,ll op)
26 {
27     ll ans=0;
28     switch(op)
29     {
30         case 1:
31             for(int i=pos;i;i-=lowbit(i))
32                 ans+=tree1[i];
33             break;
34         case 2:
35             for(int i=pos;i;i-=lowbit(i))
36                 ans+=tree2[i];
37             break;
38     }
39     return ans;
40 }
41 int main()
42 {
43     scanf("%lld%lld",&n,&m);
44     for(int i=1;i<=n;i++)
45         scanf("%lld",&num[i]),
46         add(i,num[i],1),add(i,num[i]*(i-1),2);
47     for(int i=1;i<=m;i++)
48     {
49         scanf("%s",opt);
50         if(opt[0]=='M')
51         {
52             scanf("%lld%lld",&x,&y); 
53             add(x,y-num[x],1);
54             add(x,(y-num[x])*(x-1),2);
55             num[x]=y;
56         }else if(opt[0]=='Q')
57         {
58             scanf("%lld",&x);
59             ll xx=x*ask(x,1),yy=ask(x,2);
60             printf("%lld\n",x*ask(x,1)-ask(x,2));
61         }
62     }
63     return 0;
64 }

 

相關推薦

BZOJ3155/LNSYOJ96 preprefix陣列x2報告

這道題是樹狀陣列+數學題,然而我數學並不好 題目描述 對於一個長度為nn的序列a1,a2,a3……ana1,a2,a3……an,其字首和(Prefix Sum)SiSi為前ii個元素的和,即∑k=1iai∑k=1iai。而字首和的字首和(Preprefix Sum)就是把字首和序列S1,S2,S3……Sn

FundraisingGym - 101889F陣列+最大值處理層層推進

題目連結   哇哇哇!!!好題啊,昨晚比賽時一直卡在了第6組,當時爆零,極度尷尬……不過嘛,這都是ACMer的必經之路了,然後今早起來改了下,心態調整好,想了下,發現了處理問題的方式,然後就給過了。(其實昨晚上已經找到問題所在了,只是太急了,畢竟只有2個小時,剩下半小時的時候就

計數問題JSOI2009陣列三維單修區查

傳送門:https://www.luogu.org/problemnew/show/P4054 資料很小,支援開三維 三維分別是橫縱座標和權值 這樣每次維護的時候只需要在d[x][y][key]++就行或者--。 基本也是模板,,注意一下差分那個地方,,經典的總-左-上+左上

11.2校內測試矩陣字首和陣列逆序對(題意轉換)

Solution 簽到水題,直接狀壓列舉所有情況算出答案即可。 Code #include<bits/stdc++.h> #define LL long long using namespace std; inline LL read() { LL x =

區間偶數異或和離線陣列字首和前驅思想

【連結】 http://hznu.club/OJ/problem.php?cid=1227&pid=2 【題意】 求區間出現偶數次的數的異或和 【思路】 首先,沒有修改,可以離線查詢,減少複雜度。 其次,我們容易知道的是:區間出現奇數次的數的異或和,即為區間異或和。

動態主席ZOJ 2112陣列+主席

題意:       給定一個區間,求這個區間第k小的數,支援單點修改。   思路:       動態主席樹裸題。       我們先來回顧一下靜態主席樹的做法,對於陣列中每一個位置

DNA Evolution CodeForces - 828E(827C)陣列

題目連結   很難的一道題吧,算是挺難了,就是想到挺複雜,作為我這麼個Ju蒻來說。   題目給你一串字串,是初始的字串,然後告訴你一系列操作,問你: (一)、改變點Xi上的字元; (二)、查詢【l,r】區間上的對應與新給的字串匹配的個數是幾個?例如“ACGTC

codeforce828E. DNA Evolution陣列統計貢獻

文章目錄 題目連結: 題目連結: http://codeforces.com/problemset/problem/828/E 題意:先給一個DNA序列,然後有兩種操作 操作1:把 x 位置的鹼基改成 c 操作2:給一個 L 和一個 R ,以及

POJ2155/LNSYOJ113 Matrix二維陣列+差分報告

這道題是一個二維樹狀陣列,思路十分神奇,其實還是挺水的 題目描述 給定一個N∗NN∗N的矩陣AA,其中矩陣中的元素只有0或者1,其中A[i,j]A[i,j]表示矩陣的第i行和第j列(1≤i,j≤N)(1≤i,j≤N),初始矩陣元素都是0。在矩陣上進行TT次操作,操作有以下兩種: (1)格式為C x1 y

LNSYOJ203最大值陣列應用報告+陣列深刻理解

這道題是一個典型的樹狀陣列查詢有幾個比某個數大/小的數的應用 題目描述    給定NN個區間,選定一個固定整數值TT,對於一個區間[ai,bi][ai,bi]. 如果T<aiT<ai,那麼T在這個區間的得分為X, 如果T>biT>bi,那麼T在這個區間的得分為Z, 如果ai≤

REQ CodeForces - 594D陣列+離線查詢+區間思維

題目連結   很好的一道題,昨晚上推的,今天由於程式碼能力太弱敲了半天,再不斷的找到自己思維的BUG,於是RE了一發、T了一發、WA了一發,就Ac了,還不錯,那我們來講解一下題目的思路。   我們知道對於一個值的尤拉函式值,就是它的值去乘上它所有的質數-1除以質數:如

歷屆試題 小朋友排隊陣列

  歷屆試題 小朋友排隊   時間限制:1.0s   記憶體限制:256.0MB 問題描述   n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。   每個小朋友都有一個不高興的程度。開始的時候,所有小朋友的不高興程度

CHOJ 4201 樓蘭圖騰陣列

描述 在完成了分配任務之後,西部314來到了樓蘭古城的西部。相傳很久以前這片土地上(比樓蘭古城還早)生活著兩個部落,一個部落崇拜尖刀(‘V’),一個部落崇拜鐵鍬(‘∧’),他們分別用V和∧的形狀來代表各自部落的圖騰。 西部314在樓蘭古城的下面發現了一幅巨大的壁畫,壁畫上被

2016 大連區域賽 現場賽 E—Aninteresting game陣列

Aninteresting game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 120    Acce

BZOJ P1103 「POI2007」大都市megdfs序陣列+差分

#include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include &

hdu 1166 敵兵佈陣單點更新 區間查詢陣列

敵兵佈陣 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 126415    Accepted Submissi

1082 線段練習 3區間更新 區間查詢陣列

題目描述 Description 給你N個數,有兩種操作: 1:給區間[a,b]的所有數增加X 2:詢問區間[a,b]的數的和。 輸入描述 Input Description 第一行一個正整數n,接下來n行n個整數, 再接下來一個正整數Q,每行表示操作的個數,

HDU 5592 ZYB's Game 陣列+二分

<題目連結> 題目大意: 給你一個由1~n,n個數組成的序列,給出他們每個的字首逆序數,現在要求輸出這個序列。 解題分析: 由字首逆序數很容易能夠得到每個數的逆序數。假設當前數是i,它前面比它小的數為a[i]( i - 1 - i的逆序數即可),我們不難知道,i在前i個數中是第i+1大的。

修改序列陣列區修單查模板

傳送門:http://oi.cdshishi.net:8000/problempage.php?problem_id=2138 水題++上程式碼 #include<bits/stdc++.h> #define in read() using namespace std; in

清點人數陣列單修字首和模板

題目傳送門:http://oi.cdshishi.net:8000/problempage.php?problem_id=3860 太水了,,,比模板還水,,模板好歹要帶一個r-(l-1),這個直接查字首和,,太水了 #include<bits/stdc++.h> #defi