poj 3468-A Simple Proble with Integers(樹状配列解法)
2866 ワード
A Simple Proble with Integers
Time Limit: 5000 MS
メモリLimit: 131313722 K
Total Submissions: 59247
Acceepted: 18032
Case Time Limit: 2000 MS
Description
You have N integers A 1、 A 2,… AN.You need to deal with two kids of operations.One type of operation is to add some given number to each number in a given interval.The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q.1≦ N,Q ≦100000.The second line contains N numbers,the initial values of A 1、 A 2,… AN.-100000≦ Ai ≤100000万.Each of the next Q LINE represents an operation."C a. b c「means adding」 c to each of Aa、 A+1,… Ab.-10000≦ c ≦10000."Q a. b"means querying the sum of Aa、 A+1,… Ab.
Output
You need to answer all Q command in order.One answer in a line.
Sample Input
The sums may exceed the range of 32-bit integers.
ソurce
POJ Monthly-207..11.25,Yang Yi
出自するhttp://kenby.iteye.com/blog/962159
n個の数、m回の動作、Q x yの問い合わせ[x,y]の和、C x y bの[x,y]の各数にbを加算する.
まず、1からiの初期値(a配列に記録)、Q x yの和を記録します. sum=a[y]-a[x-1]+S(動作変化の値)は、配列k[],k[i]はiからnまでの全ての値にk[i]を加算することを意味し、C x y bは
:k[x]+b,k[y+1]-b;S= Sy-S(x-1)Si=a[1]*i+a[2]*(i-1)+.a[i]*1-->> Si=(i+1)*(k[1]+k[2]+k[3].k[i]-(k[1]*1+k[2]*2+k[3]*3.
これにより、k[1]の累積からk[i]の和を要求するために、k[1]*1がk[i]*iに加算される和に変換され、ツリー配列を用いてlog(n)の時間を求めることができる.
Time Limit: 5000 MS
メモリLimit: 131313722 K
Total Submissions: 59247
Acceepted: 18032
Case Time Limit: 2000 MS
Description
You have N integers A 1、 A 2,… AN.You need to deal with two kids of operations.One type of operation is to add some given number to each number in a given interval.The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q.1≦ N,Q ≦100000.The second line contains N numbers,the initial values of A 1、 A 2,… AN.-100000≦ Ai ≤100000万.Each of the next Q LINE represents an operation."C a. b c「means adding」 c to each of Aa、 A+1,… Ab.-10000≦ c ≦10000."Q a. b"means querying the sum of Aa、 A+1,… Ab.
Output
You need to answer all Q command in order.One answer in a line.
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output4
55
9
15
ベントThe sums may exceed the range of 32-bit integers.
ソurce
POJ Monthly-207..11.25,Yang Yi
出自するhttp://kenby.iteye.com/blog/962159
n個の数、m回の動作、Q x yの問い合わせ[x,y]の和、C x y bの[x,y]の各数にbを加算する.
まず、1からiの初期値(a配列に記録)、Q x yの和を記録します. sum=a[y]-a[x-1]+S(動作変化の値)は、配列k[],k[i]はiからnまでの全ての値にk[i]を加算することを意味し、C x y bは
:k[x]+b,k[y+1]-b;S= Sy-S(x-1)Si=a[1]*i+a[2]*(i-1)+.a[i]*1-->> Si=(i+1)*(k[1]+k[2]+k[3].k[i]-(k[1]*1+k[2]*2+k[3]*3.
これにより、k[1]の累積からk[i]の和を要求するために、k[1]*1がk[i]*iに加算される和に変換され、ツリー配列を用いてlog(n)の時間を求めることができる.
#include
#include
#define LL long long int
LL a[100010] , b[100010] , c[100010] ;
int lowbit(int x)
{
return x & -x;
}
void add(LL *s,int i,int x,int n)
{
while( i <= n )
{
s[i] += x ;
i += lowbit(i) ;
}
}
LL get(LL *s,int i)
{
LL sum = 0;
while( i )
{
sum += s[i] ;
i -= lowbit(i) ;
}
return sum;
}
LL f(int i)
{
LL sum = a[i] ;
sum += ( (i+1)*get(b,i) - get(c,i) ) ;
return sum ;
}
int main()
{
int i , n , m , l , r ;
LL x , sum ;
char ch ;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
scanf("%d %d", &n, &m);
for(i = 1 ; i <= n ; i++)
{
scanf("%lld", &x);
a[i] += a[i-1] + x ;
}
while(m--)
{
getchar();
scanf("%c", &ch);
if(ch == 'Q')
{
scanf("%d %d", &l, &r);
sum = f(r) - f(l-1) ;
printf("%lld
", sum) ;
}
else
{
scanf("%d %d %d", &l, &r, &x);
add(b,l,x,n) ;
add(b,r+1,-x,n);
add(c,l, x*l ,n);
add(c,r+1, -(x*(r+1)),n);
}
}
return 0;
}