zoukankan      html  css  js  c++  java
  • The beautiful values of the palace

    给出n * n的矩阵,矩阵里有一些点存在值,现在有q个查询,查询某些矩阵里值的和
    把每次查询拆成前缀和的形式,那么利用二维偏序,对每一个查询求出比自己坐标小的值的和
    传送门
    园丁的花园就是这个模板,然后在此基础上加了一个螺旋矩阵,
    传送门可以O(1)查询某个点的数值

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int N = 1e6 + 5;
    struct Query{
        int x, y;
        ll op;
        int id;
        bool operator < (const Query &b) const {
            return x == b.x ? (y == b.y ? op : y < b.y) : x < b.x;
        }
    } q[N], tmp[N];
    int tot = 0;
    ll ans[N];
    void cdq(int l, int r){
        if(l == r) return;
        int mid = (l + r) >> 1;
        cdq(l, mid); cdq(mid + 1, r);
        int posa = l, posb = mid + 1, pos = l;
        ll tot = 0;
        while(posa <= mid && posb <= r) {
            if(q[posa].y <= q[posb].y) tot += q[posa].op, tmp[pos++] = q[posa++];
            else ans[q[posb].id] += tot, tmp[pos++] = q[posb++];
        }
        while(posa <= mid) tmp[pos++] = q[posa++];
        while(posb <= r) ans[q[posb].id] += tot, tmp[pos++] = q[posb++];
        for(int i = l; i <= r; i++) q[i] = tmp[i];
    }
    ll num(ll n, ll i, ll j){ // 螺旋矩阵O(1)查询
        i = n - i + 1, j = n - j + 1;
        ll ans = 0;
        ll minn = min(i, min(j, min(n - i + 1, n - j + 1)));
        if(i <= j) ans = minn * (4 * (n - 1) - 4 * minn) + 10 * minn - 4 * n - 3 + i + j;
        else ans = minn * (4 * n - 4 * minn) + 2 * minn + 1 - i - j;
        ll tot = 0;
        while(ans) { tot += ans % 10; ans /= 10; }
        return tot;
    }
    void solve(){
        memset(ans, 0, sizeof(ans));
        tot = 0;
        int n, m, qq;
        scanf("%d%d%d", &n, &m, &qq);
        for(int i = 1, x, y; i <= m; i++) {
            scanf("%d%d", &x, &y);
            q[++tot] = Query{x, y, num(n, x, y), 0};
        }
        int ans_tot = 0;
        for(int i = 1, x1, y1, x2, y2; i <= qq; i++) {
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            q[++tot] = Query{x2, y2, 0, ++ans_tot};
            q[++tot] = Query{x1 - 1, y2, 0, ++ans_tot};
            q[++tot] = Query{x2, y1 - 1, 0, ++ans_tot};
            q[++tot] = Query{x1 - 1, y1 - 1, 0, ++ans_tot};
        }
        sort(q + 1, q + tot + 1);
        cdq(1, tot);
        for(int i = 1; i + 3 <= ans_tot; i += 4) {
            printf("%lld
    ", ans[i] - ans[i + 1] - ans[i + 2] + ans[i + 3]);
        }
    }
    int main(){
        int t; cin >> t;
        while(t--) solve();
        return 0;
    }
    
  • 相关阅读:
    redhat 6.7 telnet rpm 安装包
    linux下网络配置 命令
    修复南尼U盘
    mac获取root权限
    ubuntu二进制包安装openresty
    ubuntu18源码包安装openresty
    Python监控rabbitmq的代码
    win10不能将文件拖到另外一个程序中去的解决办法
    docker配置远程管理端口
    nginx的代理配置
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13586643.html
Copyright © 2011-2022 走看看