poj -- 3468

 

很明显 用线段树 

 

节点类型 :

typedef struct _NODE_
{
    int L,R;
    _NODE_* pLeft;
    _NODE_* pRight;
    LL nSum;  // 原来的和
    LL lnc;      //增加量c的累加
}NODE;

感觉用孩子节点比较好一点 开到2n就行了

用2*n+1/2*n+2的话 要开到4n

 

http://poj.org/problem?id=3468

 

  1 #include<iostream>
  2 #include<cstdio>
  3 using namespace std;
  4 
  5 const int maxn = 200000 + 10;
  6 typedef long long LL;
  7 typedef struct _NODE_
  8 {
  9     int L,R;
 10     _NODE_* pLeft;
 11     _NODE_* pRight;
 12     LL nSum;
 13     LL lnc;
 14 }NODE;
 15 
 16 NODE Tree[maxn];
 17 int nCount = 0;
 18 int Mid(NODE* pRoot)
 19 {
 20     return (pRoot->L+pRoot->R)/2;
 21 }
 22 void BuildTree(NODE* pRoot,int L,int R)
 23 {
 24     pRoot->L = L;
 25     pRoot->R = R;
 26     pRoot->nSum = 0;
 27     pRoot->lnc = 0;
 28     if (L == R)
 29     {
 30         return ;
 31     }
 32     nCount++;
 33     pRoot->pLeft = Tree + nCount;
 34     nCount++;
 35     pRoot->pRight = Tree + nCount;
 36     BuildTree(pRoot->pLeft,L,(L+R)/2);
 37     BuildTree(pRoot->pRight,(L+R)/2+1,R);
 38 }
 39 void Insert(NODE* pRoot,int i,int v)
 40 {
 41     if (pRoot->L==i&&pRoot->R==i)
 42     {
 43         pRoot->nSum = v;
 44         return ;
 45     }
 46     pRoot->nSum+=v;
 47     if (i<=Mid(pRoot))
 48     {
 49         Insert(pRoot->pLeft,i,v);
 50     }
 51     else
 52     {
 53         Insert(pRoot->pRight,i,v);
 54     }
 55 }
 56 
 57 void Add(NODE* pRoot,int a,int b,LL c)
 58 {
 59     if (pRoot->L==a&&pRoot->R==b)
 60     {
 61         pRoot->lnc+=c;
 62         return ;
 63     }
 64     pRoot->nSum+=c*(b-a+1);
 65     if (b<=(pRoot->L+pRoot->R)/2)
 66     {
 67         Add(pRoot->pLeft,a,b,c);
 68     }
 69     else if (a>=(pRoot->L+pRoot->R)/2+1)
 70     {
 71         Add(pRoot->pRight,a,b,c);
 72     }
 73     else
 74     {
 75         Add(pRoot->pLeft,a,(pRoot->L+pRoot->R)/2,c);
 76         Add(pRoot->pRight,(pRoot->L+pRoot->R)/2+1,b,c);
 77     }
 78 }
 79 
 80 LL QuerynSum(NODE* pRoot,int a,int b)
 81 {
 82     if (pRoot->L==a&&pRoot->R==b)
 83     {
 84         return pRoot->nSum+(pRoot->R-pRoot->L+1)*pRoot->lnc;
 85     }
 86     
 87          
 88         pRoot->nSum += (pRoot->R-pRoot->L+1)*pRoot->lnc;
 89         Add(pRoot->pLeft,pRoot->L,Mid(pRoot),pRoot->lnc);
 90         Add(pRoot->pRight,Mid(pRoot)+1,pRoot->R,pRoot->lnc);
 91         pRoot->lnc = 0;
 92         if (b<=Mid(pRoot))
 93         {
 94             return QuerynSum(pRoot->pLeft,a,b);
 95         }
 96         else if (a>=Mid(pRoot)+1)
 97         {
 98             return QuerynSum(pRoot->pRight,a,b);
 99         }
100         else
101         {
102             return QuerynSum(pRoot->pLeft,a,Mid(pRoot))+QuerynSum(pRoot->pRight,Mid(pRoot)+1,b);
103         }
104     
105 }
106 
107 
108 void work()
109 {
110     int i,j,k;
111     int n,q;
112     scanf("%d%d",&n,&q);
113     int a,b,c;
114     nCount = 0;
115     char cmd[10];
116     BuildTree(Tree,1,n);
117     for (i = 1;i<=n;i++)
118     {
119         scanf("%d",&a);
120         Insert(Tree,i,a);
121     }
122     for (i = 0;i<q;i++)
123     {
124         scanf("%s",cmd);
125         if (cmd[0]=='C')
126         {
127             scanf("%d%d%d",&a,&b,&c);
128             Add(Tree,a,b,c);
129         }
130         else
131         {
132             scanf("%d%d",&a,&b);
133             printf("%I64d\n",QuerynSum(Tree,a,b));
134         }
135     }
136     return ;
137 }
138 int main()
139 {
140     work();
141     return 0;
142 }
代码君

posted on 2015-06-10 20:24  yifi  阅读(189)  评论(0编辑  收藏  举报

导航