zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Jessica's Reading Problem POJ
    FatMouse and Cheese HDU
    How many ways HDU
    Humble Numbers HDU
    Doing Homework again
    Stacks of Flapjacks UVA
    Party Games UVA
    24. 两两交换链表中的节点
    面试题 03.04. 化栈为队
    999. 可以被一步捕获的棋子数
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2738.html
Copyright © 2011-2022 走看看