HDU 4721 Food and Productivity (二分+树状数组)
来源:互联网 发布:matlab教程矩阵 编辑:程序博客网 时间:2024/06/06 23:51
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题意 :给出n * m的格子,每个格子有两个属性food , prod。对于每一个查询A,B,可以选择某个格子将food属性+A,prod+B,然后以这个格子为中心的正方形两个属性和的最小值最大。
http://acm.hdu.edu.cn/showproblem.php?pid=4721
其实很简单的题, 很早就会了,WA了好多天,结果是一个乘号打成了加号。。。不能更逗
由于所有属性值为正,所以没必要取边界上不完整的正方形,不过处理下也没事。。。
正方形的连长为2 * r + 1,预处理一下子矩阵和。
将所有的正方形两个属性和提取出来,离散化一下food,用BIT维护prod属性的前缀最大值。
对于每一次查询,二分答案ans , 两个属性和都要大于等于ans。
二分下food,查询一下prod的最值。
逆序后维护前缀最大值。。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <stack>#define lson step << 1#define rson step << 1 | 1#define lowbit(x) (x & (-x))#define Key_value ch[ch[root][1]][0] using namespace std;typedef long long LL;const int N = 505;int n , m , r , q;int food[N][N] , prod[N][N];int a[N * N] , b[N * N] , tot , x[N * N];int s[N * N] , cnt;void add (int x , int v) { for (int i = x ; i <= cnt ; i += lowbit (i)) { s[i] = max (s[i] , v); }}int ask (int x) { int ret = 0; for (int i = x ; i > 0 ; i -= lowbit (i)) { ret = max (ret , s[i]); } return ret;}int main () { #ifndef ONLINE_JUDGE freopen ("input.txt" , "r" , stdin); // freopen ("output.txt" , "w" , stdout); #endif int t , cas = 0; scanf ("%d" , &t); while (t --) { memset (food , 0 , sizeof(food)); memset (prod , 0 , sizeof(prod)); memset (s , 0 , sizeof(s)); scanf ("%d %d %d %d" , &n , &m , &r , &q); for (int i = 1 ; i <= n ; i ++) { for (int j = 1 ; j <= m ; j ++) { scanf ("%d" , &food[i][j]); food[i][j] += food[i - 1][j] + food[i][j - 1] - food[i - 1][j - 1]; } } for (int i = 1 ; i <= n ; i ++) { for (int j = 1 ; j <= m ; j ++) { scanf ("%d" , &prod[i][j]); prod[i][j] += prod[i - 1][j] + prod[i][j - 1] - prod[i - 1][j - 1]; } } tot = 0; r = 2 * r + 1; for (int i = r ; i <= n ; i ++) { for (int j = r ; j <= m ; j ++) { a[tot] = food[i][j] - food[i][j - r] - food[i - r][j] + food[i - r][j - r]; b[tot] = prod[i][j] - prod[i][j - r] - prod[i - r][j] + prod[i - r][j - r]; x[tot] = a[tot]; tot ++; } } sort (x , x + tot); cnt = unique (x , x + tot) - x; for (int i = 0 ; i < tot ; i ++) { int y = cnt - (lower_bound (x , x + cnt , a[i]) - x); add (y , b[i]); } printf ("Case #%d:\n" , ++ cas); while (q --) { int A , B; scanf ("%d %d" , &A , &B); int low = min (A , B) + r * r * 1 , high = min (A , B) + r * r * 3 , mid , ans; while (low <= high) { mid = (low + high) >> 1; int y = cnt - (lower_bound (x , x + cnt , mid - A) - x); if (y < 1) { high = mid - 1; continue; } int tmp = ask (y); if (tmp + B >= mid) { ans = mid; low = mid + 1; } else high = mid - 1; } printf ("%d\n" , ans); } if (t) puts (""); } return 0;}
- HDU 4721 Food and Productivity (二分+树状数组)
- HDU 4721 Food and Productivity
- HDU 5412 CRB and Queries【整体二分+树状数组】
- HDU 4311 树状数组+二分
- HDU 2852 树状数组+二分
- HDU 5493(树状数组+二分)
- hdu 5592 树状数组+二分
- HDU 4217 树状数组+二分查找
- HDU P4339(树状数组+二分查询)
- HDU 4339 Query(树状数组+二分)
- hdu(4339)树状数组+二分查找
- hdu 4302 简单树状数组二分
- hdu 2852(树状数组+二分)
- HDU ACM 5249 KPI->树状数组+二分
- HDU 5493 Queue(二分+树状数组)
- HDU-4339 Query(树状数组+二分)
- hdu 5869 RMQ+二分+离线树状数组
- HDU 5493 Queue(二分+树状数组)
- URAL 1736 Chinese Hockey(网络最大流)
- JAVA自己实现的文件压缩解压
- 最新3D思维导图软件imindmap6破解版/中文汉化版免费下载~乐趣尽在其中
- java集合类
- Jump Game II (最小步数到达终点,贪心) 【leetcode】
- HDU 4721 Food and Productivity (二分+树状数组)
- ultraedit
- Ural 1732. Ministry of Truth 多串匹配KMP
- URAL 1741 Communication Fiend
- 比较两个文件相同的地方
- POJ 2479 Maximum sum(DP)
- 调用栈
- C语言运算符优先级 详细列表
- CODE 34: Recover Binary Search Tree