bzoj2738: 矩阵乘法(整体二分)

http://www.lydsy.com/JudgeOnline/problem.php?id=2738

 

整体二分

二维树状数组累积

 

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 501
#define M 60001

#define lowbit(x) x&-x

struct Number
{
    int x,y,num;
}e[N*N];

struct Query
{
    int X1,Y1,X2,Y2;
    int k,cur;
    int id;
}f[M],tmp1[M],tmp2[M];

int n;

int c[N][N];

int ans[M],have[M];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c))  c=getchar(); 
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar();  }
}

bool cmp(Number p,Number q)
{
    return p.num<q.num;
}

void change(int x,int y,int w)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=n;j+=lowbit(j))
            c[i][j]+=w;
}

int query(int x,int y)
{
    int sum=0;
    for(int i=x;i;i-=lowbit(i))
        for(int j=y;j;j-=lowbit(j))
            sum+=c[i][j];
    return sum;
}

void solve(int head,int tail,int l,int r)
{
    if(head>tail) return;
    if(l==r)
    {
        for(int i=head;i<=tail;++i) ans[f[i].id]=e[l].num;
        return;
    }
    int mid=l+r>>1;
    for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,1);
    for(int i=head;i<=tail;++i) 
        have[f[i].id]=query(f[i].X2,f[i].Y2)-query(f[i].X1-1,f[i].Y2)-query(f[i].X2,f[i].Y1-1)+query(f[i].X1-1,f[i].Y1-1);
    for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,-1);
    int ll=0,rr=0;
    for(int i=head;i<=tail;++i)
    {
        if(have[f[i].id]+f[i].cur>=f[i].k) tmp1[++ll]=f[i];
        else
        {
            f[i].cur+=have[f[i].id];
            tmp2[++rr]=f[i];
        }
    }
    for(int i=1;i<=ll;++i) f[head+i-1]=tmp1[i];
    for(int i=1;i<=rr;++i) f[head+ll+i-1]=tmp2[i];
    solve(head,head+ll-1,l,mid);
    solve(head+ll,tail,mid+1,r);
}

int main()
{
    int q;
    read(n); read(q);
    int tot=0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        {
            e[++tot].x=i;
            e[tot].y=j;
            read(e[tot].num);
        }
    sort(e+1,e+tot+1,cmp);
    for(int i=1;i<=q;++i)
    {
        read(f[i].X1);
        read(f[i].Y1);
        read(f[i].X2);
        read(f[i].Y2);
        read(f[i].k);
        f[i].id=i;
    }
    solve(1,q,1,tot);
    for(int i=1;i<=q;++i) cout<<ans[i]<<'\n';
}
posted @ 2017-12-19 14:29  TRTTG  阅读(274)  评论(0编辑  收藏  举报