解题思路:
先用数组累计从1~n的杀敌数,所以从i~j的杀敌数就是sum[j]-sum[i-1];
进行加的时候再用线段树进行单点更新m次时间复杂度就是O(mlogn)
查找时先从累加数组中计算出最开始的杀敌数再去线段树中计算后来的杀敌数
m次时间复杂度就是O(mlogn)
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 struct node 5 { 6 int l,r; 7 int sum; 8 int mid() 9 { 10 return (l+r)/2; 11 } 12 }; 13 int num[1000005]; 14 node t[4000005]; 15 int n,q; 16 int ans=0; 17 void init(int root,int l,int r) 18 { 19 t[root].l=l; 20 t[root].r=r; 21 t[root].sum=0; 22 if(l==r) return; 23 else 24 { 25 init(2*root+1,l,t[root].mid()); 26 init(2*root+2,t[root].mid()+1,r); 27 } 28 } 29 void in(int root,int i,int num) 30 { 31 t[root].sum+=num; 32 if(i==t[root].l&&i==t[root].r) return; 33 else if(i<=t[root].mid()) 34 in(2*root+1,i,num); 35 else 36 in(2*root+2,i,num); 37 } 38 void qu(int root,int l,int r) 39 { 40 if(t[root].l==l&&t[root].r==r) 41 { 42 ans+=t[root].sum; 43 return; 44 } 45 if(r<=t[root].mid()) 46 { 47 qu(2*root+1,l,r); 48 } 49 else if(l>t[root].mid()) 50 { 51 qu(2*root+2,l,r); 52 } 53 else 54 { 55 qu(2*root+1,l,t[root].mid()); 56 qu(2*root+2,t[root].mid()+1,r); 57 } 58 } 59 60 int main() 61 { 62 scanf("%d",&n); 63 scanf("%d",&q); 64 init(0,1,n); 65 memset(num,0,sizeof(num)); 66 for(int i=1;i<=n;i++) 67 { 68 scanf("%d",&num[i]); 69 num[i]=num[i]+num[i-1]; 70 } 71 char str[15]; 72 int a,b; 73 for(int i=0;i<q;i++) 74 { 75 scanf("%s",str); 76 if(str[0]==‘A‘) 77 { 78 scanf("%d%d",&a,&b); 79 in(0,a,b); 80 } 81 if(str[0]==‘Q‘) 82 { 83 ans=0; 84 scanf("%d%d",&a,&b); 85 qu(0,a,b); 86 printf("%d\n",ans+num[b]-num[a-1]); 87 } 88 } 89 }
时间: 2024-10-11 19:21:25