tsinsen A1333
可以用二维树状数组套值域线段树来做,复杂度:O( (n*n+q) * logn logn log10^9 )
但作为作为整体二分的例题,还是用整体二分来写了一下。对整体二分有一点感觉了。
整体二分,顾名思义,二分答案,只不过不是对单独一个询问,而是对所有询问,具体过程可以想象成对询问的不断分类(根据其答案区间不断往下分)。比如最开始所有询问的答案区间是[amin,amax],我们现在分出两个区间[amin,amid],和[amid+1,amax],然后将当前区间[amin,amax]的所有询问根据某些信息,分配到两个区间,使得其答案的可能的区间范围就是它所属的区间,当区间长度为1时,该区间包含的询问的答案就是该区间的那个数。
形象一点,可以把二分比作赶鸭子(询问)回窝(答案),单独对一个询问二分是只赶一只鸭子,向左区间或右区间赶,直到回窝,而整体二分就是赶一群鸭子,前者只需单刀直入,找到答案,而后者还需要回朔。
整体二分的优势是可以在分配询问时共享一些东西,从而避免掉每次单独算的低效,从而优化复杂度。
#include <cstdio>
#include <vector>
#include <algorithm>
#define oo 0x3f3f3f3f
#define N 510
#define M 60010
using namespace std; struct Pair {
int v;
int x, y;
Pair(){}
Pair( int v, int x, int y ):v(v),x(x),y(y){}
bool operator<( const Pair &o ) const {
return v<o.v;
}
};
bool operator<( const Pair &a, int b ) {
return a.v<b;
}
bool operator<( int a, const Pair &b ) {
return a<b.v;
}
struct Query {
int id;
int xmin, xmax;
int ymin, ymax;
int k;
Query( int id, int x0, int x1, int y0, int y1, int k ):
id(id),xmin(x0),xmax(x1),ymin(y0),ymax(y1),k(k){}
}; int n, m;
int ww[N][N], vmin, vmax;
int bit[N][N];
int ans[M];
Pair prs[N*N]; int ptot;
vector<Query> vq;
int q[N*N]; void modify( int x, int y, int v ) {
for( register int i=x; i<=n; i+=i&-i )
for( register int j=y; j<=n; j+=j&-j )
bit[i][j] += v;
}
int query( int x, int y ) {
int rt = ;
for( register int i=x; i; i-=i&-i )
for( register int j=y; j; j-=j&-j )
rt += bit[i][j];
return rt;
}
int query( int xmin, int xmax, int ymin, int ymax ) {
return query(xmax,ymax)-query(xmin-,ymax)-query(xmax,ymin-)+query(xmin-,ymin-);
}
void binary( int lf, int rg, vector<Query> vq ) {
if( vq.empty() ) return;
if( lf==rg ) {
for( int t=; t<vq.size(); t++ )
ans[vq[t].id] = lf;
return;
}
int mid=lf+((rg-lf)>>);
int lpos = lower_bound( prs+, prs++ptot, lf ) - prs;
int rpos = upper_bound( prs+, prs++ptot, mid ) - prs - ;
for( int i=lpos; i<=rpos; i++ )
modify( prs[i].x, prs[i].y, + );
vector<Query> ql, qr;
for( int t=; t<vq.size(); t++ ) {
int c = query( vq[t].xmin, vq[t].xmax, vq[t].ymin, vq[t].ymax );
if( vq[t].k<=c )
ql.push_back( vq[t] );
else {
qr.push_back( vq[t] );
qr.back().k -= c;
}
}
for( int i=lpos; i<=rpos; i++ )
modify( prs[i].x, prs[i].y, - );
binary( lf, mid, ql );
binary( mid+, rg, qr );
}
int main() {
scanf( "%d%d", &n, &m );
vmin=oo, vmax=-oo;
for( int i=; i<=n; i++ )
for( int j=; j<=n; j++ ) {
scanf( "%d", &ww[i][j] );
vmin = min( vmin, ww[i][j] );
vmax = max( vmax, ww[i][j] );
prs[++ptot] = Pair( ww[i][j], i, j );
}
sort( prs+, prs++ptot );
for( int i=,x0,x1,y0,y1,k; i<=m; i++ ) {
scanf( "%d%d%d%d%d", &x0, &y0, &x1, &y1, &k );
vq.push_back( Query( i, x0, x1, y0, y1, k ) );
}
binary( vmin, vmax, vq );
for( int i=; i<=m; i++ )
printf( "%d\n", ans[i] );
}
tsinsen A1333的更多相关文章
- Tsinsen A1333: 矩阵乘法(整体二分)
http://www.tsinsen.com/A1333 题意:-- 思路:和之前的第k小几乎一样,只不过把一维BIT换成二维BIT而已.注意二维BIT写法QAQ #include <cstdi ...
- tsinsen A1333. 矩阵乘法(梁 盾)
A1333. 矩阵乘法(梁 盾) 时间限制:2.0s 内存限制:256.0MB 总提交次数:515 AC次数:211 平均分:54.14 将本题分享到: 查看未格式化 ...
- tsinsen A1333. 矩阵乘法
题目链接:传送门 题目思路:整体二分(二分的是答案,附带的是操作) 把矩阵中的元素对应成插入操作,然后就有插入和询问操作. 然后根据插入操作对于答案的影响,询问操作所匹配的符合答案个数,将操作分为两段 ...
- 整体二分learning
整体二分是一个离线的做法 目前可以解决求区间第k大问题 当然划分树主席树都可以的样子.. 为什么我老学一些解决同种问题的算法.. 主要思想大概是这样的: 如果要求[l,r]的区间第K大 而这个区间内 ...
- 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法
整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...
- Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)
题目 Source http://www.tsinsen.com/A1493 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在 ...
- 【Tsinsen】【A1365】森林旅店
KD-Tree 啊哈~检验了一下自己KD-Tree的学习情况,还算可以,模板至少是记下来了. 支持插入(所以要带重建),查询最近的P个点的距离. 然而题目并没有说是按怎样的顺序输出这P个点?...(事 ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- Tsinsen A1303. tree(伍一鸣) (LCT+处理标记)
[题目链接] http://www.tsinsen.com/A1303 [题意] 给定一棵树,提供树上路径乘/加一个数,加边断边,查询路径和的操作. [思路] LCT+传标 一次dfs构造LCT. L ...
随机推荐
- Java高性能并发编程——线程池
在通常情况下,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的 ...
- Linux移植随笔:对tslib库的ts_test测试程序代码的一点分析【转】
转自:http://www.latelee.org/embedded-linux/porting-linux-tstest-code.html 本文是作者对tslib库的ts_test.c文件进行分析 ...
- spring boot 测试用例
junit 是一个面向于研发人员使用的轻量的测试模块,适合做单元测试.而testng百度后发现更强大,可以做功能测试,但对于我这种RD,貌似junit足沟了呢! java Mock PowerMock ...
- cout如何输出十六进制
http://blog.csdn.net/okadler0518/article/details/4962340 cout<<hex<<i<<endl; //输出十 ...
- linux cpu、内存、硬盘空间查询
[CPU] 算式: CPU总核数 = 物理CPU个数 * 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 * 每颗物理CPU的核数 * 超线程数 #查看CPU型号 cat /proc/cpu ...
- Eclipse中各种编码格式及设置
操作系统:Windows 10(家庭中文版) Eclipse版本:Version: Oxygen.1a Release (4.7.1a) 刚看到一篇文章,里面介绍说Ascii.Unicode是编码,而 ...
- c语言双向循环链表
双向循环链表,先来说说双向链表,双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继 ...
- Windows平台的rop exp编写
摘抄自看雪 Windows的ROP与Linux的ROP并不相同,其实Linux下的应该叫做是ret2libc等等.Windows的ROP有明确的执行目标,比如开辟可执行内存然后拷贝shellcode, ...
- 【LOJ】 #2025. 「JLOI / SHOI2016」方
题解 有什么LNOI啊,最后都是JLOI罢了 一道非常--懵逼的统计题 当然是容斥,所有的方案 - 至少有一个点坏掉的正方形 + 至少有两个点坏掉的正方形 - 至少有三个点坏掉的正方形 + 至少有四个 ...
- Django实战(20):分页(Pagination)
在上一节我们实现了针对某个产品的订单订阅功能.但是我们可能需要直接在站点上查询所有的订单.显然,随着时间的增长订单会越来越多,所以分页(Pagination)是个好办法:每次只显示一部分订单. 分页是 ...