您的位置:首页 > 其它

poj 3468 块状链表 区间修改+区间查询

2015-05-02 10:10 316 查看
经典的线段树题目,也可以用块链来做。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

typedef __int64 ll;
const ll M = 400;
ll b[M][M];
ll add[M];
ll sum[M];
ll n, m, ps;

ll query( ll l, ll r )
{
ll cur = l / ps, ncur = r / ps;
l = l % ps, r = r % ps;
ll res = 0;
for ( ll i = cur + 1; i <= ncur - 1; i++ )
{
res += sum[i] + ps * add[i];
}
if ( cur != ncur )
{
for ( ll j = l; j < ps; j++ )
{
res += b[cur][j];
}
res += add[cur] * ( ps - l );
for ( ll j = 0; j <= r; j++ )
{
res += b[ncur][j];
}
res += ( r + 1 ) * add[ncur];
}
else
{
for ( ll j = l; j <= r; j++ )
{
res += b[cur][j];
}
res += add[cur] * ( r - l + 1 );
}
return res;
}

void update( ll l, ll r, ll d )
{
ll cur = l / ps, ncur = r / ps;
l = l % ps, r = r % ps;
for ( ll i = cur + 1; i < ncur; i++ )
{
add[i] += d;
}
if ( cur != ncur )
{
for ( ll j = l; j < ps; j++ )
{
b[cur][j] += d;
}
sum[cur] += d * ( ps - l );
for ( ll j = 0; j <= r; j++ )
{
b[ncur][j] += d;
}
sum[ncur] += d * ( r + 1 );
}
else
{
for ( ll j = l; j <= r; j++ )
{
b[cur][j] += d;
}
sum[cur] += ( r - l + 1 ) * d;
}
}

int main ()
{
ps = 350;
while ( scanf("%I64d%I64d", &n, &m) != EOF )
{
memset( sum, 0, sizeof(sum) );
memset( add, 0, sizeof(add) );
for ( ll i = 0; i < n; i++ )
{
ll tmp; scanf("%I64d", &tmp);
b[i / ps][i % ps] = tmp;
sum[i / ps] += tmp;
}
char op[2];
ll l, r, d;
while ( m-- )
{
scanf("%s%I64d%I64d", op, &l, &r);
l--, r--;
if ( op[0] == 'Q' )
{
printf("%I64d\n", query( l, r ));
}
else
{
scanf("%I64d", &d);
update( l, r, d );
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: