zoukankan      html  css  js  c++  java
  • JZOJ 4754.矩阵

    ( ext{Problem})

    ( ext{Solution})

    纪念我考场正解被二分暴力暴踩。。。
    首先二分的话,显然可以二分出答案,然后数矩阵和大于等于本矩阵的是否有 (k)
    加一些优化就可以 (AC)?!!
    不管它,正解就是让矩阵行列大小从小到大扩展,矩阵和小一些的肯定已经出来了
    (k) 次即可,注意判重
    本人手打哈希表+手打堆,因为数组开小光荣 ( ext{RE} 80pts)
    欲哭无泪

    ( ext{Code})

    #include <cstdio>
    #include <iostream>
    #define LL long long
    #define re register
    #define register
    using namespace std;
    
    const int N = 1005, mod = 1e6 + 7;
    int n, m, ma, mb, k, a[N][N];
    LL s[N][N];
    
    inline void read(int &x)
    {
    	x = 0; char ch = getchar();
    	while (ch < '0' || ch > '9') ch = getchar();
    	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    }
    
    struct Hash{int x, y, nxt;}e[mod * 2 + 5];
    int ht[mod + 5], tot;
    inline void insert(int x, int y)
    {
    	int key = (10000000LL * x + y) % mod;
    	e[++tot] = Hash{x, y, ht[key]}, ht[key] = tot;
    }
    inline int query(int x, int y)
    {
    	int key = (10000000LL * x + y) % mod;
    	for(re int i = ht[key]; i; i = e[i].nxt) 
    		if (e[i].x == x && e[i].y == y) return 1;
    	return 0;
    }
    
    struct node{int x0, y0, x1, y1; LL s;};
    struct Heap{
    	int size;
    	node h[N * N * 2];
    	
    	inline int check(int x, int y)
    	{
    		if (x > 0 && y > 0 && x <= n && y <= m) return 1;
    		return 0;
    	}
    	inline int Num(int x, int y){return (x - 1) * m + y;}
    	inline node top(){return h[1];}
    	inline void pop(){h[1] = h[size--], down(1);}
    	
    	inline void up(int x){while (x > 1 && h[x].s < h[x >> 1].s) swap(h[x], h[x >> 1]), x >>= 1;}
    	inline void down(int x)
    	{
    		while (((x << 1) <= size && h[x].s > h[x << 1].s) || ((x << 1 | 1) <= size && h[x].s > h[x << 1 | 1].s))
    		{
    			int y = x << 1;
    			if (h[y | 1].s < h[y].s) y |= 1;
    			swap(h[x], h[y]), x = y;
    		}
    	}
    	
    	inline void push(node c)
    	{
    		if (!(check(c.x0, c.y0) && check(c.x1, c.y1))) return;
    		if (query(Num(c.x0, c.y0), Num(c.x1, c.y1))) return;
    		insert(Num(c.x0, c.y0), Num(c.x1, c.y1));
    		c.s = s[c.x1][c.y1] - s[c.x0 - 1][c.y1] - s[c.x1][c.y0 - 1] + s[c.x0 - 1][c.y0 - 1];
    		h[++size] = c;
    		up(size);
    	}
    }T;
    
    int main()
    {
    	read(n), read(m), read(ma), read(mb), read(k);
    	for(re int i = 1; i <= n; i++)
    		for(re int j = 1; j <= m; j++)
    			read(a[i][j]), s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
    	for(re int i = 1; i <= n - ma + 1; i++)
    		for(re int j = 1; j <= m - mb + 1; j++) T.push(node{i, j, i + ma - 1, j + mb - 1});
    	LL ans = -1; node now;
    	for(re int i = 1; i <= k; i++)
    	{
    		now = T.top(), T.pop();
    		if (i == k){ans = now.s; break;}
    		T.push(node{now.x0, now.y0, now.x1, now.y1 + 1});
    		T.push(node{now.x0, now.y0, now.x1 + 1, now.y1});
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    LintCode-Search for a Range
    LintCode-Serialization and Deserialization Of Binary Tree
    LeetCode-Reverse Words in a String
    LeetCode-Reorder List
    LeetCode-Word Break
    LeetCode-Word Ladder
    LeetCode-Valid Palindrome
    cf div2 237 D
    POJ 1759
    cf div2 238 D
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15132831.html
Copyright © 2011-2022 走看看