首页 > 代码库 > 模板 分块

模板 分块

分块模板
单点加 区间求和
时间复杂度 Q * sqrt(N)

 

 1 #include <bits/stdc++.h> 
 2 #define For(i,j,k) for(int i=j;i<=k;i++) 
 3 #define LL long long 
 4 #define eps 1e-9
 5 using namespace std ; 
 6 
 7 const int N = 100011 ; 
 8 int n,Q,size,cnt,pos,x ; 
 9 LL ans ; 
10 int a[N] ;  
11 char s[2] ; 
12 struct node{
13     LL sum ; 
14 }tree[ 330 ];   //  sqrt  
15 
16 inline int read() 
17 {
18     int x = 0 , f = 1 ; 
19     char ch = getchar() ; 
20     while(ch<0||ch>9) { if(ch==-) f = -1 ; ch = getchar(); } 
21     while(ch>=0&&ch<=9) { x = x * 10+ch-48 ; ch = getchar(); } 
22     return x * f ; 
23 }
24 
25 inline int what_cnt(int pos)        // 查询当前位置是属于哪一块中的   
26 {
27     return (pos-1) / size + 1 ;
28 }
29 
30 inline void build(int pos)        //  暴力重构一块 
31 {
32     int L = (pos-1) * size+1 ;    
33     int R = pos * size ; 
34     LL sum = 0 ; 
35     For(i,L,R) sum+=a[ i ] ;  
36     tree[pos].sum = sum ; 
37 }
38 
39 inline LL query(int x,int y)               
40 {
41     int L = what_cnt(x) ; 
42     int R = what_cnt(y) ;
43     LL sum = 0 ; 
44     if(L==R) {
45         For(i,x,y) sum+=a[ i ] ;           // 在同一块中要特殊处理 
46         return sum ; 
47     } 
48     For(i,x,L*size) sum+=a[ i ] ;          //   加掉边沿的  
49     For(i,(R-1)*size+1,y) sum+=a[ i ] ; 
50     For(i,L+1,R-1) sum+=tree[ i ].sum ; 
51     return sum ; 
52 }
53 
54 int main() 
55 {
56     n = read() ; Q = read() ; 
57     size = int(sqrt( n )+eps) ; 
58     cnt = (n-1) / size+1 ; 
59     //For(pos,1,cnt) build( pos ) ; 
60     
61     while(Q--) {
62         scanf("%s",s) ; 
63         if(s[ 0 ]==x) {
64             x = read() ; 
65             a[ x ]+=read() ; 
66             pos = what_cnt( x ) ; 
67             build( pos ) ; 
68         }
69         else { 
70             int L = read() ; int R = read() ;  
71             ans = query(L,R) ; 
72             printf("%lld\n",ans) ; 
73         }
74      }     
75     return 0 ; 
76 }

 

模板 分块