hdu1166-敌兵布阵-分块

把区间分成√n份降低复杂度.

 1 #include<bits/stdc++.h>
 2 
 3 #define inf 0x3f3f3f3f
 4 
 5 const int maxn=50000;
 6 
 7 const int seg=223;
 8 
 9 using namespace std;
10 
11 int t,n,icase,x,y;
12 
13 char order[maxn/10000+10];
14 
15 int a[maxn+10];
16 
17 int sum[maxn+10];
18 
19 void Add(int x,int y){
20     a[x]+=y;
21     sum[x/seg+1]+=y;
22 }
23 
24 int query(int l,int r){
25     int res=0;
26     int L=l/seg+1,R=r/seg+1;
27     if(L==R||R==L+1){
28         for(int i=l;i<=r;i++){
29                 res+=a[i];
30         }
31     } else {
32        for(int i=l;i<=L*seg-1;i++){
33            res+=a[i];
34        }
35        for(int i=r;i>=(R-1)*seg;i--){
36            res+=a[i];
37        }
38        for(int i=L+1;i<=R-1;i++){
39            res+=sum[i];
40        }
41     }
42   return res;
43 }
44 
45 void solve(){
46     scanf("%d",&n);
47     for(int i=0;i<n;i++){
48         scanf("%d",&a[i]);
49     }
50     for(int i=0;i<n;i++){
51         sum[i/seg+1]+=a[i];
52     }
53     printf("Case %d:\n",++icase);
54     while(scanf("%s",order)!=EOF){
55         if(order[0]=='E'){
56            break;
57         } else if(order[0]=='A'){
58                 scanf("%d%d",&x,&y);
59                 x--;
60                 Add(x,y);
61         } else if(order[0]=='S'){
62                 scanf("%d%d",&x,&y);
63                 x--;
64                 Add(x,-y);
65         }
66          else if(order[0]=='Q'){
67                 scanf("%d%d",&x,&y);
68                 x--,y--;
69                 int ans=query(x,y);
70                 printf("%d\n",ans);
71         }
72     }
73 }
74 
75 void init(){
76   memset(a,0,sizeof(a));
77   memset(sum,0,sizeof(sum));
78 }
79 
80 int main()
81 {
82     scanf("%d",&t);
83     while(t--){
84         init();
85         solve();
86     }
87     return 0;
88 }

 

转载于:https://www.cnblogs.com/GeniusYang/p/5766513.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值