poj -- 3468
2015-06-10 20:24
330 查看
很明显 用线段树
节点类型 :
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
代码君
节点类型 :
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
#include<iostream> #include<cstdio> using namespace std; const int maxn = 200000 + 10; typedef long long LL; typedef struct _NODE_ { int L,R; _NODE_* pLeft; _NODE_* pRight; LL nSum; LL lnc; }NODE; NODE Tree[maxn]; int nCount = 0; int Mid(NODE* pRoot) { return (pRoot->L+pRoot->R)/2; } void BuildTree(NODE* pRoot,int L,int R) { pRoot->L = L; pRoot->R = R; pRoot->nSum = 0; pRoot->lnc = 0; if (L == R) { return ; } nCount++; pRoot->pLeft = Tree + nCount; nCount++; pRoot->pRight = Tree + nCount; BuildTree(pRoot->pLeft,L,(L+R)/2); BuildTree(pRoot->pRight,(L+R)/2+1,R); } void Insert(NODE* pRoot,int i,int v) { if (pRoot->L==i&&pRoot->R==i) { pRoot->nSum = v; return ; } pRoot->nSum+=v; if (i<=Mid(pRoot)) { Insert(pRoot->pLeft,i,v); } else { Insert(pRoot->pRight,i,v); } } void Add(NODE* pRoot,int a,int b,LL c) { if (pRoot->L==a&&pRoot->R==b) { pRoot->lnc+=c; return ; } pRoot->nSum+=c*(b-a+1); if (b<=(pRoot->L+pRoot->R)/2) { Add(pRoot->pLeft,a,b,c); } else if (a>=(pRoot->L+pRoot->R)/2+1) { Add(pRoot->pRight,a,b,c); } else { Add(pRoot->pLeft,a,(pRoot->L+pRoot->R)/2,c); Add(pRoot->pRight,(pRoot->L+pRoot->R)/2+1,b,c); } } LL QuerynSum(NODE* pRoot,int a,int b) { if (pRoot->L==a&&pRoot->R==b) { return pRoot->nSum+(pRoot->R-pRoot->L+1)*pRoot->lnc; } pRoot->nSum += (pRoot->R-pRoot->L+1)*pRoot->lnc; Add(pRoot->pLeft,pRoot->L,Mid(pRoot),pRoot->lnc); Add(pRoot->pRight,Mid(pRoot)+1,pRoot->R,pRoot->lnc); pRoot->lnc = 0; if (b<=Mid(pRoot)) { return QuerynSum(pRoot->pLeft,a,b); } else if (a>=Mid(pRoot)+1) { return QuerynSum(pRoot->pRight,a,b); } else { return QuerynSum(pRoot->pLeft,a,Mid(pRoot))+QuerynSum(pRoot->pRight,Mid(pRoot)+1,b); } } void work() { int i,j,k; int n,q; scanf("%d%d",&n,&q); int a,b,c; nCount = 0; char cmd[10]; BuildTree(Tree,1,n); for (i = 1;i<=n;i++) { scanf("%d",&a); Insert(Tree,i,a); } for (i = 0;i<q;i++) { scanf("%s",cmd); if (cmd[0]=='C') { scanf("%d%d%d",&a,&b,&c); Add(Tree,a,b,c); } else { scanf("%d%d",&a,&b); printf("%I64d\n",QuerynSum(Tree,a,b)); } } return ; } int main() { work(); return 0; }
代码君
相关文章推荐
- hdu1142(最短路+记忆化搜索)
- (leetcode)Remove Duplicates from Sorted List
- Xcode6在iPhone5+iOS7模拟器上编译,上下有黑边问题
- System权限下进程遇到的问题以及如何降权启动进程
- 【VB.NET机房重构】SQLHelper--数据库小助手
- Majority Element
- 我们都爱大长腿
- Algorithms—22.Generate Parentheses
- XX项目总结
- uva 10397 Connect the Campus(最小生成树kruskal)
- 二进制bomb实验第三弹
- android:layout_gravity 和 android:gravity 的区别
- sprintf函数
- Canjs基础教程之Controls
- HDU - 2059 龟兔赛跑(多阶段决策dp)
- 线程与进程的区别
- oracle record is locked by another user
- DFS Path Sum II
- 仿英语流利说取词放大控件的实现
- Java——(四)Collection之Set集合TreeSet类