码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2989

时间:2017-08-26 15:05:27      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:bzoj   src   坐标轴   splay   const   ons   space   转化   hid   

坐标轴转化+cdq分治

我们发现那个绝对值不太好搞,于是我们把曼哈顿距离转为欧几里得距离,x‘=x-y,y‘=x+y,这样两点之间距离就是max(|x1‘-x2‘|,|y1‘-y2‘|),这个距离要小于等于k,那么就是求转化后坐标系中在以x‘,y‘为中心,边长为2k的正方形中的点数,每次修改就相当于加入一个点,计算平面点数就是cdq分治,按时间排序,对x分治,y插入树状数组,然后就做好了

技术分享
#include<bits/stdc++.h>
using namespace std;
const int N = 400010, base = 200010;
struct query {
    int x, y, opt, minus, id;
    query(int x = 0, int y = 0, int opt = 0, int minus = 0, int id = 0) : x(x), y(y), opt(opt), minus(minus), id(id) {}
    bool friend operator < (query A, query B) {
        return A.x == B.x ? A.id < B.id : A.x < B.x;
    }
} q[N << 1];
vector<query> c;
int n, Q, cnt, tot, m;
int ans[N], a[N], tree[N << 1];
void update(int x, int d) { for(; x <= m; x += x & (-x)) tree[x] += d; }
int ask(int x) { int ret = 0; for(; x; x -= x & (-x)) ret += tree[x]; return ret; }
void cdq(int l, int r)
{
    if(l >= r) return;
    int mid = (l + r) >> 1;
    cdq(l, mid); cdq(mid + 1, r);
    c.clear();
    for(int i = l; i <= mid; ++i) if(q[i].opt == 1) c.push_back(q[i]);
    for(int i = mid + 1; i <= r; ++i) if(q[i].opt == 2) c.push_back(q[i]);
    sort(c.begin(), c.end());
    for(int i = 0; i < c.size(); ++i)
    {
        query o = c[i];
        if(o.opt == 1) update(o.y, 1);
        else ans[o.id] += ask(o.y) * o.minus;
    }
    for(int i = 0; i < c.size(); ++i) if(c[i].opt == 1) update(c[i].y, -1);
}
int main()
{
    scanf("%d%d", &n, &Q);
    for(int i = 1; i <= n; ++i) 
    {
        scanf("%d", &a[i]);
        q[++cnt] = query(i - a[i], i + a[i] + base, 1, 0, 0);
        m = max(m, i + a[i] + base);
    }
    for(int i = 1; i <= Q; ++i)
    {
        char s[10];
        int x, y, k;
        scanf("%s", s);
        if(s[0] == M) 
        {
            scanf("%d%d", &x, &y);
            q[++cnt] = query(x - y, x + y + base, 1, 0, 0), a[x] = y;
            m = max(m, x + y + base);
        }       
        if(s[0] == Q) 
        {
            scanf("%d%d", &x, &k);
            ++tot;
            m = max(m, x + a[x] + k + base);
            q[++cnt] = query(x - a[x] + k, x + a[x] + k + base, 2, 1, tot); 
            q[++cnt] = query(x - a[x] - k - 1, x + a[x] - k - 1 + base, 2, 1, tot);
            q[++cnt] = query(x - a[x] - k - 1, x + a[x] + k + base, 2, -1, tot);
            q[++cnt] = query(x - a[x] + k, x + a[x] - k - 1 + base, 2, -1, tot);    
        }
    }
    cdq(1, cnt);
    for(int i = 1; i <= tot; ++i) printf("%d\n", ans[i]); 
    return 0;
}
View Code

 

bzoj2989

标签:bzoj   src   坐标轴   splay   const   ons   space   转化   hid   

原文地址:http://www.cnblogs.com/19992147orz/p/7435207.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!