poj 3468 A Simple Problem with Integers(线段树)
题目链接:http://poj.org/problem?id=3468
典型的线段树问题,(插线问线)
这题有两个易错点,占存点需要是(long long )WA了好几次,关于选段树数组的大小 一般N*6吧(关于这点我在poj上亲自测试了)
代码:
1 #include <stdio.h> 2 #include <string.h> 3 4 typedef struct tree 5 { 6 int l,r; 7 long long sum; 8 long long ans; 9 }tree; 10 11 tree tree_list[600010]; 12 int a[100005]; 13 14 void build(int i,int x,int n) 15 { 16 tree_list[i].l = x; 17 tree_list[i].r = n; 18 tree_list[i].ans = 0; 19 if(x == n) 20 { 21 tree_list[i].sum = a[x]; 22 return; 23 } 24 int mid = (x+n)/2; 25 build(i<<1,x,mid); 26 build(i<<1 | 1,mid+1,n); 27 tree_list[i].sum = tree_list[i<<1].sum + tree_list[i<<1 | 1].sum; 28 } 29 30 void print(int i) 31 { 32 printf("i == %d %lld\n",i,tree_list[i].sum); 33 if(tree_list[i].l == tree_list[i].r) 34 return ; 35 print(i<<1); 36 print(i<<1 |1); 37 } 38 void add(int i,int l1,int r1,int x) 39 { 40 if(tree_list[i].l == l1 && tree_list[i].r == r1) 41 { 42 tree_list[i].ans += x; 43 return ; 44 } 45 tree_list[i].sum += x*(r1 - l1+1);//该区间的值 46 int mid = (tree_list[i].l + tree_list[i].r) /2; 47 if(r1 <= mid) 48 add(i<<1,l1,r1,x); 49 else if(l1 > mid) 50 add(i<<1 |1,l1,r1,x); 51 else 52 { 53 add(i<<1,l1,mid,x); 54 add(i<<1 | 1,mid+1,r1,x); 55 } 56 57 } 58 59 long long query(int i,int l1,int r1) 60 { 61 if(tree_list[i].ans != 0) 62 { 63 tree_list[i].sum += (tree_list[i].r - tree_list[i].l +1 )* tree_list[i].ans; 64 tree_list[i<<1].ans += tree_list[i].ans; 65 tree_list[i<<1 | 1].ans += tree_list[i].ans; 66 tree_list[i].ans = 0; 67 } 68 69 if(tree_list[i].l == l1 && tree_list[i].r == r1) 70 { 71 return tree_list[i].sum; 72 } 73 else 74 { 75 int mid = (tree_list[i].l + tree_list[i].r ) /2; 76 if(r1 <= mid) 77 return query(i<<1,l1,r1); 78 else if(l1 > mid) 79 return query(i<<1 |1,l1,r1); 80 else 81 return query(i<<1,l1,mid) + query(i<<1|1,mid+1,r1); 82 } 83 } 84 int main() 85 { 86 int n,m,i,x,y,z; 87 char ch[5]; 88 while(~scanf("%d%d",&n,&m)) 89 { 90 memset(a,0,sizeof(a)); 91 memset(tree_list,0,sizeof(tree_list)); 92 for(i = 1; i <= n; i++) 93 scanf("%d",&a[i]); 94 /*for(i = 1; i <= n; i++) 95 printf("%d ",a[i]); 96 printf("\n");*/ 97 build(1,1,n); 98 // print(1); 99 while(m--) 100 { 101 scanf("%s",ch); 102 if(ch[0] == 'Q') 103 { 104 scanf("%d%d",&x,&y); 105 printf("%lld\n",query(1,x,y)); 106 } 107 else 108 { 109 scanf("%d%d%d",&x,&y,&z); 110 add(1,x,y,z); 111 } 112 } 113 } 114 return 0; 115 }
yy_room