zoukankan      html  css  js  c++  java
  • tsinsen A1333

    可以用二维树状数组套值域线段树来做,复杂度:O( (n*n+q) * logn logn log10^9 )

    但作为作为整体二分的例题,还是用整体二分来写了一下。对整体二分有一点感觉了。

    整体二分,顾名思义,二分答案,只不过不是对单独一个询问,而是对所有询问,具体过程可以想象成对询问的不断分类(根据其答案区间不断往下分)。比如最开始所有询问的答案区间是[amin,amax],我们现在分出两个区间[amin,amid],和[amid+1,amax],然后将当前区间[amin,amax]的所有询问根据某些信息,分配到两个区间,使得其答案的可能的区间范围就是它所属的区间,当区间长度为1时,该区间包含的询问的答案就是该区间的那个数。

    形象一点,可以把二分比作赶鸭子(询问)回窝(答案),单独对一个询问二分是只赶一只鸭子,向左区间或右区间赶,直到回窝,而整体二分就是赶一群鸭子,前者只需单刀直入,找到答案,而后者还需要回朔。

    整体二分的优势是可以在分配询问时共享一些东西,从而避免掉每次单独算的低效,从而优化复杂度。

      1 #include <cstdio>
      2 #include <vector>
      3 #include <algorithm>
      4 #define oo 0x3f3f3f3f
      5 #define N 510
      6 #define M 60010
      7 using namespace std;
      8 
      9 struct Pair {
     10     int v;
     11     int x, y;
     12     Pair(){}
     13     Pair( int v, int x, int y ):v(v),x(x),y(y){}
     14     bool operator<( const Pair &o ) const {
     15         return v<o.v;
     16     }
     17 };
     18 bool operator<( const Pair &a, int b ) {
     19     return a.v<b;
     20 }
     21 bool operator<( int a, const Pair &b ) {
     22     return a<b.v;
     23 }
     24 struct Query {
     25     int id;
     26     int xmin, xmax;
     27     int ymin, ymax;
     28     int k;
     29     Query( int id, int x0, int x1, int y0, int y1, int k ):
     30         id(id),xmin(x0),xmax(x1),ymin(y0),ymax(y1),k(k){}
     31 };
     32 
     33 int n, m;
     34 int ww[N][N], vmin, vmax;
     35 int bit[N][N];
     36 int ans[M];
     37 Pair prs[N*N]; int ptot;
     38 vector<Query> vq;
     39 int q[N*N];
     40 
     41 void modify( int x, int y, int v ) {
     42     for( register int i=x; i<=n; i+=i&-i )
     43         for( register int j=y; j<=n; j+=j&-j )
     44             bit[i][j] += v;
     45 }
     46 int query( int x, int y ) {
     47     int rt = 0;
     48     for( register int i=x; i; i-=i&-i )
     49         for( register int j=y; j; j-=j&-j )
     50             rt += bit[i][j];
     51     return rt;
     52 }
     53 int query( int xmin, int xmax, int ymin, int ymax ) {
     54     return query(xmax,ymax)-query(xmin-1,ymax)-query(xmax,ymin-1)+query(xmin-1,ymin-1);
     55 }
     56 void binary( int lf, int rg, vector<Query> vq ) {
     57     if( vq.empty() ) return;
     58     if( lf==rg ) {
     59         for( int t=0; t<vq.size(); t++ ) 
     60             ans[vq[t].id] = lf;
     61         return;
     62     }
     63     int mid=lf+((rg-lf)>>1);
     64     int lpos = lower_bound( prs+1, prs+1+ptot, lf ) - prs;
     65     int rpos = upper_bound( prs+1, prs+1+ptot, mid ) - prs - 1;
     66     for( int i=lpos; i<=rpos; i++ ) 
     67         modify( prs[i].x, prs[i].y, +1 );
     68     vector<Query> ql, qr;
     69     for( int t=0; t<vq.size(); t++ ) {
     70         int c = query( vq[t].xmin, vq[t].xmax, vq[t].ymin, vq[t].ymax );
     71         if( vq[t].k<=c ) 
     72             ql.push_back( vq[t] );
     73         else {
     74             qr.push_back( vq[t] );
     75             qr.back().k -= c;
     76         }
     77     }
     78     for( int i=lpos; i<=rpos; i++ ) 
     79         modify( prs[i].x, prs[i].y, -1 );
     80     binary( lf, mid, ql );
     81     binary( mid+1, rg, qr );
     82 }
     83 int main() {
     84     scanf( "%d%d", &n, &m );
     85     vmin=oo, vmax=-oo;
     86     for( int i=1; i<=n; i++ )
     87         for( int j=1; j<=n; j++ ) {
     88             scanf( "%d", &ww[i][j] );
     89             vmin = min( vmin, ww[i][j] );
     90             vmax = max( vmax, ww[i][j] );
     91             prs[++ptot] = Pair( ww[i][j], i, j );
     92         }
     93     sort( prs+1, prs+1+ptot );
     94     for( int i=1,x0,x1,y0,y1,k; i<=m; i++ ) {
     95         scanf( "%d%d%d%d%d", &x0, &y0, &x1, &y1, &k );
     96         vq.push_back( Query( i, x0, x1, y0, y1, k ) );
     97     }
     98     binary( vmin, vmax, vq );
     99     for( int i=1; i<=m; i++ )
    100         printf( "%d
    ", ans[i] );
    101 }
    View Code
  • 相关阅读:
    一些内容
    ios开发 xcode6以上安装Alcatraz管理插件
    java锁的深度化-重入锁,读写锁,乐观锁,悲观锁
    并发队列
    并发工具类
    并发编程
    HashMap底层源码剖析
    双列集合map面试题
    单列集合List
    类加载
  • 原文地址:https://www.cnblogs.com/idy002/p/4463524.html
Copyright © 2011-2022 走看看