• bzoj2738 矩阵乘法


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2738

    【题解】

    整体二分,然后用二维树状数组(单点修改区间查询)统计即可。

    不知道为什么跑的特别慢(可能是我的整体二分常数太大?)

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10, N = 510;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    inline int read() {
        int x = 0, f = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while(isdigit(ch)) {
            x = (x<<3) + (x<<1) + ch - '0';
            ch = getchar();
        }
        return x*f;
    }
    
    int n, Q;
    struct quest {
        int x1, y1, x2, y2, k;
        quest() {}
        quest(int x1, int y1, int x2, int y2, int k) : x1(x1), y1(y1), x2(x2), y2(y2), k(k) {}
        inline void set() {
            x1 = read(), y1 = read(), x2 = read(), y2 = read(), k = read();
        }
    }a[M];
    
    struct pa {
        int x, y, d;
        pa() {}
        pa(int x, int y, int d) : x(x), y(y), d(d) {}
        friend bool operator < (pa a, pa b) {
            return a.d < b.d;
        }
    }p[M]; int pn = 0;
    
    
    struct BIT {
        int c[N][N];
        # define lb(x) (x&(-x))
        inline void set(int _n) {
            n = _n;
            memset(c, 0, sizeof c);
        }
        inline void edt(int x, int y, int d) {
            for (int i=x; i<=n; i+=lb(i))
                for (int j=y; j<=n; j+=lb(j))
                    c[i][j] += d;
        }
        inline int sum(int x, int y) {
            int ret = 0;
            for (int i=x; i; i-=lb(i))
                for (int j=y; j; j-=lb(j))
                    ret += c[i][j];
            return ret;
        }
        inline int sum(int x1, int y1, int x2, int y2) {
            return sum(x2, y2) - sum(x2, y1-1) - sum(x1-1, y2) + sum(x1-1, y1-1);
        }
    }T;
                    
    int id[M], ans[M], cur[M], t1[M], t2[M];
    inline void solve(int l, int r, int al, int ar, int fr) {
        if(al > ar) return ;
        if(l == r) {
            for (int i=al; i<=ar; ++i) ans[id[i]] = l;
            return ;
        }
    //    printf("%d %d %d %d %d
    ", l, r, al, ar, fr);
        int mid = l+r>>1, ed, t1n, t2n; t1n = t2n = 0;
        for (ed=fr; ed<=pn; ++ed) {
            if(p[ed].d > mid) break;
            T.edt(p[ed].x, p[ed].y, 1);
        }
        for (int i=al, t; i<=ar; ++i) {
            int x = id[i];
            if((t = cur[x] + T.sum(a[x].x1, a[x].y1, a[x].x2, a[x].y2)) >= a[x].k) t1[++t1n] = x;
            else t2[++t2n] = x, cur[x] = t;
    //        printf("id = %d, t = %d
    ", x, t);
        }
    //    printf("%d %d
    ", t1n, t2n);
        for (int i=fr; i<ed; ++i) T.edt(p[i].x, p[i].y, -1);
        int tn = al-1;
        for (int i=1; i<=t1n; ++i) id[++tn] = t1[i];
        t1n = tn;
        for (int i=1; i<=t2n; ++i) id[++tn] = t2[i];
        solve(l, mid, al, t1n, fr);
        solve(mid+1, r, t1n+1, ar, ed);        
    }
    
    int main() {
        int mx = 0;
        n = read(), Q = read();
        T.set(n);
        for (int i=1, t; i<=n; ++i) 
            for (int j=1; j<=n; ++j) {
                t = read();
                mx = max(mx, t);
                p[++pn] = pa(i, j, t);
            }
        sort(p+1, p+pn+1);
        for (int i=1; i<=Q; ++i) id[i] = i, a[i].set();
        solve(0, mx, 1, Q, 1);
        for (int i=1; i<=Q; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    实例化对象
    面向对象
    合并类动态规划——石子合并(洛谷1880)
    合并类动态规划——能量项链(洛谷1063)
    multiplicationoverview
    cadence 工艺库各文件夹所包含的内容
    C语言读入文件的函数列举
    一篇工程师的感悟(转载)
    验证汇总一些缩写代码含义
    Verilog代码覆盖率检查
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2738.html
Copyright © 2020-2023  润新知