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 }

 

posted @ 2013-08-23 21:39  heity  阅读(316)  评论(0编辑  收藏  举报