MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
先前做了这一题, 不过是用 树状数组做的, 对于这一类型的题目也来说非常方便快捷. 具体地址 : http://www.cnblogs.com/MiYu/archive/2010/08/25/1808441.html
这几天学了 线段树 , 不是很明白它的用途 和 使用方法, 因为 听说 树状数组是 线段树的 一种特殊情况 ( 部分资料是这么说的 ) . 于是就又做了一次这个题目.
不过使用的是线段树的 方法 :
代码如下 :
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
/*
MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
http://www.cnblog.com/MiYu
Author By : MiYu
Test : 3
Program : 1166
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct Line{ //线段树结构体
friend struct optLine;
Line () { sum = 0; left = right = NULL; };
int l,r,sum;
struct Line *left, *right;
}L;
typedef struct optLine { //线段树操作结构
void Creat ( struct Line *node, int beg, int end );
void modify ( struct Line *node, int pos,int val );
int quy ( struct Line *node, int beg, int end );
}OPT;
void optLine::Creat ( struct Line *node, int beg, int end ){ //建树
node->l = beg; node->r = end;
if ( beg == end ) return;
int mid = ( node->l + node->r ) >> 1;
L *p = new L; L *q = new L;
node->left = p; node->right = q;
Creat ( p, beg, mid ); Creat ( q, mid + 1, end );
}
void optLine::modify ( struct Line *node, int pos, int val ){ //修改
if ( pos >= node->l && pos <= node->r ) node->sum += val;
if ( node->l == node->r ) return;
int mid = ( node->l + node->r ) >> 1;
if ( mid >= pos ) modify ( node->left, pos, val );
else if ( mid < pos ) modify ( node->right, pos,val );
}
int optLine::quy ( struct Line *node, int beg, int end ){ //查询
int sum = 0; int mid = ( node->l + node->r ) >> 1;
if ( node->l == beg && node->r == end ) return node->sum;
if ( mid >= end ) return sum += quy ( node->left, beg,end );
else if ( beg > mid ) return sum += quy ( node->right, beg, end );
else {
return sum += quy ( node->left, beg, mid ) + quy ( node->right, mid+1,end );
}
}
inline bool scan_ud(int &num)
{
char in;
in=getchar();
if(in==EOF) return false;
while(in<'0'||in>'9') in=getchar();
num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
return true;
}
int main ( int T, int N )
{
scan_ud ( T );
for ( int ca = 1; ca <= T ; ++ ca ){
printf ( "Case %d:\n",ca );
scan_ud ( N ); OPT opt; L *root = new L; int val,x,y;
opt.Creat ( root, 1, N );
for ( int i = 1; i <= N; ++ i ){
scan_ud ( val ); opt.modify ( root, i, val );
}
char ask[10];
while ( scanf ( "%s", ask ), ask[0] != 'E' ){
scanf ( "%d%d",&x,&y );
switch ( ask[0] ){
case 'Q': printf ( "%d\n",opt.quy ( root, x,y ) ); break;
case 'A': opt.modify ( root, x, y ); break;
case 'S': opt.modify ( root, x, -y ); break;
}
}
}
return 0;
}
MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
http://www.cnblog.com/MiYu
Author By : MiYu
Test : 3
Program : 1166
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct Line{ //线段树结构体
friend struct optLine;
Line () { sum = 0; left = right = NULL; };
int l,r,sum;
struct Line *left, *right;
}L;
typedef struct optLine { //线段树操作结构
void Creat ( struct Line *node, int beg, int end );
void modify ( struct Line *node, int pos,int val );
int quy ( struct Line *node, int beg, int end );
}OPT;
void optLine::Creat ( struct Line *node, int beg, int end ){ //建树
node->l = beg; node->r = end;
if ( beg == end ) return;
int mid = ( node->l + node->r ) >> 1;
L *p = new L; L *q = new L;
node->left = p; node->right = q;
Creat ( p, beg, mid ); Creat ( q, mid + 1, end );
}
void optLine::modify ( struct Line *node, int pos, int val ){ //修改
if ( pos >= node->l && pos <= node->r ) node->sum += val;
if ( node->l == node->r ) return;
int mid = ( node->l + node->r ) >> 1;
if ( mid >= pos ) modify ( node->left, pos, val );
else if ( mid < pos ) modify ( node->right, pos,val );
}
int optLine::quy ( struct Line *node, int beg, int end ){ //查询
int sum = 0; int mid = ( node->l + node->r ) >> 1;
if ( node->l == beg && node->r == end ) return node->sum;
if ( mid >= end ) return sum += quy ( node->left, beg,end );
else if ( beg > mid ) return sum += quy ( node->right, beg, end );
else {
return sum += quy ( node->left, beg, mid ) + quy ( node->right, mid+1,end );
}
}
inline bool scan_ud(int &num)
{
char in;
in=getchar();
if(in==EOF) return false;
while(in<'0'||in>'9') in=getchar();
num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
return true;
}
int main ( int T, int N )
{
scan_ud ( T );
for ( int ca = 1; ca <= T ; ++ ca ){
printf ( "Case %d:\n",ca );
scan_ud ( N ); OPT opt; L *root = new L; int val,x,y;
opt.Creat ( root, 1, N );
for ( int i = 1; i <= N; ++ i ){
scan_ud ( val ); opt.modify ( root, i, val );
}
char ask[10];
while ( scanf ( "%s", ask ), ask[0] != 'E' ){
scanf ( "%d%d",&x,&y );
switch ( ask[0] ){
case 'Q': printf ( "%d\n",opt.quy ( root, x,y ) ); break;
case 'A': opt.modify ( root, x, y ); break;
case 'S': opt.modify ( root, x, -y ); break;
}
}
}
return 0;
}