您的位置:首页 > 其它

BZOJ 2989 数列

2017-03-16 08:00 330 查看
CDQ分治+树状数组

注意到这题修改操作对询问的贡献独立,且修改之间互不影响,考虑CDQ分治。用左边的修改更新右边,只需按x排序所有事件点,树状数组维护y轴即可。

不知道KD树能不能搞一搞?

#include<cstdio>
#include<algorithm>
#define lowbit(_i) (_i&-_i)
#define N 800005
#define BASE 400005
using namespace std;
namespace runzhe2000
{
int read()
{
int r = 0; char c = getchar();
for(; c < '0' || c > '9'; c = getchar());
for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar());
return r;
}
char str[10];
int n, Q, a
, qcnt, ans
;
struct BIT
{
int t
;
void mod(int x, int v){for(;x<N;x+=lowbit(x)) t[x] += v;}
int _que(int x){int r = 0; for(;x;x-=lowbit(x)) r += t[x]; return r;}
int que(int l, int r){return _que(r) - _que(l-1);}
} bit;
struct que
{
int type, x, y, d, id; // 0 insert 1 query // 1 add_query -1 del_query
bool operator < (const que &that) const
{
if(x != that.x) return x < that.x;
else return type > that.type;
}
}q
, qq[N<<1];
void dc(int l, int r)
{
if(l == r) return; int mid = (l+r)>>1, qqcnt = 0;
for(int i = l; i <= mid  ; i++) if(!q[i].type) qq[++qqcnt] = q[i];
for(int i = mid+1; i <= r; i++) if(q[i].type)
{
qq[++qqcnt] = (que){1 , q[i].x - q[i].d, q[i].y, q[i].d, q[i].id};
qq[++qqcnt] = (que){-1, q[i].x + q[i].d, q[i].y, q[i].d, q[i].id};
}
sort(qq+1, qq+1+qqcnt);
for(int i = 1; i <= qqcnt; i++)
{
if(qq[i].type == 0) bit.mod(qq[i].y, 1);
else if(qq[i].type == 1) ans[qq[i].id] -= bit.que(qq[i].y - qq[i].d, qq[i].y + qq[i].d);
else ans[qq[i].id] += bit.que(qq[i].y - qq[i].d, qq[i].y + qq[i].d);
}
for(int i = 1; i <= qqcnt; i++) if(qq[i].type == 0) bit.mod(qq[i].y, -1);
dc(l,mid); dc(mid+1,r);
}
void main()
{
n = read(); Q = read();
for(int i = 1; i <= n; i++)
{
a[i] = read();
q[++qcnt] = (que){0, i+a[i]+BASE, i-a[i]+BASE, 0, 0};
}
for(int i = 1; i <= Q; i++)
{
scanf("%s",str);
if(str[0] == 'Q'){int p = read(); q[++qcnt] = (que){1, p+a[p]+BASE, p-a[p]+BASE, read(), i};}
else {int p = read(); a[p] = read(); q[++qcnt] = (que){0, p+a[p]+BASE, p-a[p]+BASE, 0, 0};}
}
dc(1,qcnt);
for(int i = 1; i <= Q; i++) if(ans[i]) printf("%d\n",ans[i]);
}
}
int main()
{
runzhe2000::main();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: