ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ 2738. 矩阵乘法

2020-01-26 14:52:03  阅读:250  来源: 互联网

标签:ch int getc 2738 char cnt1 inline BZOJ 乘法


 

整体二分加上一个二维树状数组数点即可。

#include <bits/stdc++.h>

namespace IO {
    char buf[1 << 21], *p1 = buf, *p2 = buf;
    int p, p3 = -1;
    void read() {}
    inline int getc() {
        return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
    }
    template <typename T, typename... T2>
    inline void read(T &x, T2 &... oth) {
        T f = 1; x = 0;
        char ch = getc();
        while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getc(); }
        while (isdigit(ch)) { x = x * 10 + ch - 48; ch = getc(); }
        x *= f;
        read(oth...);
    }
}

const int N = 507;
const int M = 500 * 500 + 6e4 + 7;
int w[M], n, Q;

struct Bit {
    int tree[N][N];
    inline int lowbit(int x) { return x & -x; }
    inline void add(int x, int y, int v) {
        for (int i = x; i <= n; i += lowbit(i))
            for (int j = y; j <= n; j += lowbit(j))
                tree[i][j] += v;
    }
    inline int query(int x, int y) {
        int ans = 0;
        for (int i = x; i; i -= lowbit(i))
            for (int j = y; j; j -= lowbit(j))
                ans += tree[i][j];
        return ans;
    }
    inline int query(int x1, int yy1, int x2, int y2) {
        return query(x2, y2) + query(x1 - 1, yy1 - 1) - query(x2, yy1 - 1) - query(x1 - 1, y2);
    }
} bit;

struct Node {
    int x1, yy1, x2, y2, k, id;
} q[M], q1[M], q2[M];
int ans[M];

void solve(int l, int r, int L, int R) {
    if (l > r || L > R) return;
    if (l == r) {
        for (int i = L; i <= R; i++)
            if (q[i].id) 
                ans[q[i].id] = w[l];
        return;
    }
    int mid = l + r >> 1;
    int cnt1 = 0, cnt2 = 0;
    for (int i = L; i <= R; i++) {
        if (q[i].id) {
            int sum = bit.query(q[i].x1, q[i].yy1, q[i].x2, q[i].y2);
            if (q[i].k > sum) q[i].k -= sum, q2[++cnt2] = q[i];
            else q1[++cnt1] = q[i];
        } else {
            if (q[i].k <= w[mid]) bit.add(q[i].x1, q[i].yy1, 1), q1[++cnt1] = q[i];
            else q2[++cnt2] = q[i];
        }
    }
    for (int i = 1; i <= cnt1; i++)
        if (!q1[i].id)
            bit.add(q1[i].x1, q1[i].yy1, -1);
    for (int i = 1; i <= cnt1; i++)
        q[L + i - 1] = q1[i];
    for (int i = 1; i <= cnt2; i++)
        q[L + cnt1 + i - 1] = q2[i];
    solve(l, mid, L, L + cnt1 - 1);
    solve(mid + 1, r, L + cnt1, R);
}

int main() {
    IO::read(n, Q);
    int ccnt = 0, cnt = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            int x;
            IO::read(x);
            w[++ccnt] = x;
            ++cnt;
            q[cnt].x1 = i; q[cnt].yy1 = j;
            q[cnt].k = x;
        }
    for (int i = 1; i <= Q; i++) {
        ++cnt;
        IO::read(q[cnt].x1, q[cnt].yy1, q[cnt].x2, q[cnt].y2, q[cnt].k);
        q[cnt].id = i;
    }
    std::sort(w + 1, w + 1 + ccnt);
    ccnt = std::unique(w + 1, w + 1 + ccnt) - w - 1;
    solve(1, ccnt, 1, cnt);
    for (int i = 1; i <= Q; i++)
        printf("%d\n", ans[i]);
    return 0;
}
View Code

 

标签:ch,int,getc,2738,char,cnt1,inline,BZOJ,乘法
来源: https://www.cnblogs.com/Mrzdtz220/p/12234195.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有