1926: [Sdoi2010]粟粟的书架

http://www.lydsy.com/JudgeOnline/images/1926.jpg

大概就是分情况乱搞。。

经典维护二维前缀和暴力+莫队算法

垫底QAQ


#include <bits/stdc++.h>
using namespace std;
namespace my_useful_tools {
#define rep(_i, _k, _j) for(int _i = _k; _i <= _j; ++_i)
#define foreach(_i, _s) for(typeof(_s.begin()) _i = _s.begin(); _i != _s.end(); ++_i)
#define pb push_back
#define mp make_pair
#define ipir pair<int, int>
#define ivec vector<int>
#define clr(t) memset(t, 0, sizeof t)
#define pse(t, v) memset(t, v, sizeof t)
#define brl puts("")
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    const int INF = 0x3f3f3f3f;
    typedef long long LL;
    typedef double DB;
    inline void pc(char c) { putchar(c); }
    template<class T> inline T gcd(T a, T b) { return b == 0 ? a : gcd(b, a % b); }
    template<class T> inline void W(T p) { if(p < 0) pc('-'), p = -p; if(p / 10 != 0) W(p / 10); pc('0' + p % 10); } // warning!! slower than printf
    template<class T> inline void Wn(T p) { W(p), brl; } template<class T> inline void W(T a, T b) { W(a), pc(' '), W(b); }
    template<class T> inline void Wn(T a, T b) { W(a), pc(' '), Wn(b); }
    template<class T> inline void W(T a, T b, T c) { W(a), pc(' '), W(b), pc(' '), W(c); } 
    inline char gchar() { char ret = getchar(); for(; ret == '\n' || ret == '\r' || ret == ' '; ret = getchar()); return ret; }
    template<class T> inline void fr(T&ret) { char c = ' '; int flag = 1; for(c = getchar(); c != '-' && !('0' <= c && c <= '9'); c = getchar()); 
        if(c == '-') flag = -1, ret = 0; else ret = c - '0'; for(c = getchar(); '0' <= c && c <= '9'; c = getchar()) ret = ret * 10 + c - '0';
        ret = ret * flag;
    }
    inline int fr() { int x; fr(x); return x; }
    template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
    template<class T> inline T fast_pow(T base, T index, T mod = 2147483647, T ret = 1) {
        for(; index; index >>= 1, base = base * base % mod) if(index & 1) ret = ret * base % mod;
        return ret;
    }
    const int maxv = 100, maxe = 100;
    struct Edge {
        int edge, head[maxv], to[maxe], next[maxe];
        Edge() { edge = 0; memset(head, -1, sizeof head); }
        void addedge(int u, int v) {
            to[edge] = v, next[edge] = head[u];
            head[u] = edge++;
        }
    };
};
using namespace my_useful_tools;
 
int r, c, m;
 
class matrixCase {
    static const int maxSize = 200 + 10;
    static const int maxColor = 1000 + 10;
    int sum[maxSize][maxSize][maxColor];
    public:
    void solve() {
        for(int i = 1; i <= r; ++i)
            for(int j = 1; j <= c; ++j)
                ++sum[i][j][fr()];
        for(int i = 1; i <= r; ++i)
            for(int j = 1; j <= c; ++j)
                for(int k = 1000; 0 < k; --k)
                    sum[i][j][k] += sum[i - 1][j][k] + sum[i][j - 1][k] - sum[i - 1][j - 1][k];
        while(m--) {
            int x, y, a, b, need, use = 0;
            fr(x, y), fr(a, b, need);
            for(int i = 1000; 0 < i; --i) {
                int val = sum[a][b][i] + sum[x - 1][y - 1][i] - sum[a][y - 1][i] - sum[x - 1][b][i];
                if(val * i < need) {
                    need -= val * i, use += val;
                } else {
                    use += (need - 1) / i + 1;
                    printf("%d\n", use);
                    need = 0;
                    break;
                }
            }
            if(need) puts("Poor QLW");
        }
    }
};
 
int pos[500000 + 100];
 
class lineCase {
    static const int maxSize = 500000 + 100;
    static const int maxQuery = 20000 + 100;
     
    public:
 
    int sum[maxSize], ans[maxQuery], a[maxSize];
    struct QueryInfo {
        int l, r, need, id;
        void read(int _id) {
            fr(id, l), fr(id, r, need), id = _id;
        }
        bool operator < (const QueryInfo&rhs) const {
            return pos[l] < pos[rhs.l] || (pos[l] == pos[rhs.l] && r < rhs.r);
        }
    } q[maxQuery];
    void solve() {
        int blockSize = (int)sqrt((DB)c + 0.5);
        rep(i, 1, m) pos[i] = (i - 1) / blockSize + 1;
        rep(i, 1, c) fr(a[i]);
        for(int i = 1; i <= m; ++i) q[i].read(i);
        sort(q + 1, q + m + 1);
        int l = 1, r = 0;
        clr(sum);
        for(int i = 1; i <= m; ++i) {
            while(l < q[i].l) --sum[a[l++]];
            while(r < q[i].r) ++sum[a[++r]];
            while(q[i].l < l) ++sum[a[--l]];
            while(q[i].r < r) --sum[a[r--]];
            int use = 0;
            for(int k = 1000; 0 < k && q[i].need; --k) {
                if(sum[k] * k < q[i].need) q[i].need -= sum[k] * k, use += sum[k];
                else {
                    use += (q[i].need - 1) / k + 1;
                    q[i].need = 0;
                }
            }
    //      printf("%d\n", use);
            ans[q[i].id] = (q[i].need == 0) ? use : -1;
        }
        rep(i, 1, m) {
            if(ans[i] == -1) {
                puts("Poor QLW");
            } else {
                printf("%d\n", ans[i]);
            }
        }
    }
};
 
int main() {
    fr(r, c, m);
    if(r != 1) {
        (new matrixCase)->solve();
    } else {
        (new lineCase)->solve();
    }
 
    return 0;
}
posted @ 2014-10-30 22:34 sbit 阅读(...) 评论(...) 编辑 收藏