1081 線段樹練習 2 單點查詢及區間修改

自為風月馬前卒發表於2017-05-08

1081 線段樹練習 2

 

時間限制: 1 s
空間限制: 128000 KB
題目等級 : 大師 Master
 
 
 
題目描述 Description

給你N個數,有兩種操作


1:給區間[a,b]的所有數都增加X


2:詢問第i個數是什麼?

輸入描述 Input Description

第一行一個正整數n,接下來n行n個整數,再接下來一個正整數Q,表示操作的個數. 接下來Q行每行若干個整數。如果第一個數是1,後接3個正整數a,b,X,表示在區間[a,b]內每個數增加X,如果是2,後面跟1個整數i, 表示詢問第i個位置的數是多少。

輸出描述 Output Description

對於每個詢問輸出一行一個答案

樣例輸入 Sample Input

3

1

2

3

2

1 2 3 2

2 3

樣例輸出 Sample Output

5

資料範圍及提示 Data Size & Hint

資料範圍

1<=n<=100000

1<=q<=100000

分類標籤 Tags

 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 int n,m;
 7 const int MAXN=100001;
 8 int ans=0;
 9 struct node
10 {
11     int l,r,w,f;
12 }tree[MAXN*4];
13 inline void updata(int k)
14 {
15     tree[k].w=tree[k*2].w+tree[k*2+1].w;
16 }
17 inline void build(int k,int ll,int rr)
18 {
19     tree[k].l=ll;tree[k].r=rr;
20     if(tree[k].l==tree[k].r)
21     {
22         scanf("%d",&tree[k].w);
23         return ;
24     }
25     int m=(ll+rr)/2;
26     build(k*2,ll,m);
27     build(k*2+1,m+1,rr);
28     updata(k);
29 }
30 
31 inline void down(int k)
32 {
33     tree[k*2].f+=tree[k].f;
34     tree[k*2+1].f+=tree[k].f;
35     tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
36     tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
37     tree[k].f=0;
38 }
39 inline void interval_change(int k,int ll,int rr,int v)
40 {
41     if(tree[k].l>=ll&&tree[k].r<=rr)
42     {
43         tree[k].w+=(tree[k].r-tree[k].l+1)*v;
44         tree[k].f+=v;
45         return ;
46     }
47     if(tree[k].f)    down(k);
48     int m=(tree[k].l+tree[k].r)/2;
49     if(ll<=m)    interval_change(k*2,ll,rr,v);
50     if(rr>m)    interval_change(k*2+1,ll,rr,v);
51     updata(k);
52 }
53 inline void point_ask(int k,int p)
54 {
55     if(tree[k].l==tree[k].r)
56     {
57         ans=tree[k].w;
58         return ;
59     }
60     if(tree[k].f)    down(k);
61     int m=(tree[k].l+tree[k].r)/2;
62     if(p<=m)    point_ask(k*2,p);
63     else point_ask(k*2+1,p);
64 }
65 int main()
66 {
67     scanf("%d",&n);
68     build(1,1,n);
69     scanf("%d",&m);
70     for(int i=1;i<=m;i++)
71     {
72         int how;
73         scanf("%d",&how);
74         if(how==1)//區間修改
75         {
76             int x,y,v;
77             scanf("%d%d%d",&x,&y,&v);
78             interval_change(1,x,y,v);
79         }
80         else//單點查詢 
81         {
82             int p;
83             scanf("%d",&p);
84             ans=0;
85             point_ask(1,p);
86             printf("%d\n",ans);
87         } 
88     }
89     return 0;
90 }

 

相關文章