zoukankan      html  css  js  c++  java
  • bzoj4170 极光

    题目链接

    题面

    题意

    把每个位置的点都看成是一个二维坐标系中的点。比如第(i)个点就是((i,a[i]))
    有两种操作
    询问:然后每次询问的就是与当前点坐标的曼哈顿距离小于等于(k)的点。
    修改:修改第i个点的纵坐标。保留历史点。

    思路

    旋转坐标系。然后就变成了添加一个点和询问一个子矩阵内点的个数。用(CDQ)分治或者其他数据结构做就行了

    代码

    /*
    * @Author: wxyww
    * @Date:   2019-02-15 08:38:47
    * @Last Modified time: 2019-02-15 10:16:11
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N = 4000010,M = 3000003,BL = 1000000;
    #define  pi pair<int,int>
    ll read() {
        ll x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') {
            if(c=='-') f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9') {
            x=x*10+c-'0';
            c=getchar();
        }
        return x*f;
    }
    struct node {
        int x,y,opt,pos,val;
    }a[M];
    char s[10];
    int tt[N],tot;
    int tree[M],mx,ans[N];
    vector<pi>v;
    void update(int pos,int c) {
        while(pos <= BL*3) {
            tree[pos] += c;
            pos += pos & -pos;
        }
    }
    int query(int pos) {
        int ret = 0;
        while(pos) {
            ret += tree[pos];
            pos -= pos & -pos;
        }
        return ret;
    }
    node tmp[N];
    void cdq(int l,int r) {
        if(r <= l) return;
        int mid = (l + r) >> 1;
        cdq(l,mid);cdq(mid + 1,r);
        int now = l,L = l,R = mid + 1;
        while(L <= mid && R <= r) {
            if(a[L].x <= a[R].x) {
                if(a[L].opt == 1) {
                    update(a[L].y,a[L].val);
                    v.push_back(make_pair(a[L].y,a[L].val));
                }
                tmp[now++] = a[L++];
            }
            else {
                if(a[R].opt == 2) ans[a[R].pos] += query(a[R].y);
                else if(a[R].opt == 3) ans[a[R].pos] -= query(a[R].y);
                tmp[now++] = a[R++];
            }
        }
        while(L <= mid) tmp[now++] = a[L++];
        while(R <= r) {
            if(a[R].opt == 2) ans[a[R].pos] += query(a[R].y);
            else if(a[R].opt == 3) ans[a[R].pos] -= query(a[R].y);
            tmp[now++] = a[R++];
        }
        for(int i = l;i <= r;++i) a[i] = tmp[i];
        int k = v.size();
        for(int i = 0;i < k;++i) update(v[i].first,-v[i].second);
        v.clear();
    }
    int main() {
        int n = read(),Q = read(),now = 0;
        for(int i = 1;i <= n;++i) {
            tt[i] = read();
            a[++tot].x = i + tt[i],a[tot].y = i - tt[i] + BL;
            a[tot].opt = 1;a[tot].val = 1;
            mx = max(mx,max(a[tot].x,a[tot].y));
        }
        for(int i = 1;i <= Q;++i) {
            scanf("%s",s + 1);
            int x = read(),y = read();
            if(s[1] == 'Q') {
                int x1 = x + tt[x] - y,x2 = x + tt[x] + y,y1 = x - tt[x] + BL - y,y2 = x - tt[x] + BL + y; 
                a[++tot].pos = ++now;a[tot].x = x2;a[tot].y = y2;a[tot].opt = 2;
                a[++tot].pos = now;a[tot].x = x1 - 1;a[tot].y = y1 - 1;a[tot].opt = 2;
                a[++tot].pos = now;a[tot].x = x1 - 1;a[tot].y = y2;a[tot].opt = 3;
                a[++tot].pos = now;a[tot].x = x2;a[tot].y = y1 - 1;a[tot].opt = 3;
            }
            else {tt[x] = y;
                a[++tot].opt = 1;
                a[tot].x = x + tt[x];a[tot].y = x - tt[x] + BL;a[tot].val = 1;
                mx = max(mx,max(a[tot].x,a[tot].y));
            }
        }    cdq(1,tot);
        for(int i = 1;i <= now;++i) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    Hbase JavaApi
    面向对象特征之继承
    重写(Override)与重载(Overload)
    数组排序
    EL表达式
    java异常
    业务代码与非业务代码
    设计思想之高内聚低耦合
    JDBC实现动态查询
    枚举
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj4170.html
Copyright © 2011-2022 走看看