Cod sursa(job #2091542)

Utilizator stefdascalescuStefan Dascalescu stefdascalescu Data 19 decembrie 2017 20:19:01
Problema Struti Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include<bits/stdc++.h>
using namespace std;
ifstream f("struti.in");
ofstream g("struti.out");
int n,m,mat[1002][1002],aib[8002],q;
int minm,nr;
void add(int nod, int val)
{
    for(;nod<=8001;nod+=(nod&(-nod)))
        aib[nod]+=val;
}
int Compute(int nod)
{
    int sol=0;
    for(;nod;nod-=(nod&(-nod)))
        sol+=aib[nod];
    return sol;
}
int Bin_Search(int caut)
{
    int b=1;
    int e=8001;
    while(b<=e)
    {
        int m=(b+e)/2;
        int sol=Compute(m);
        int sol2=Compute(m-1);
        if(caut==0){
            if(sol>0 && sol2==0)
                return m;
            if(sol>0)
                e=m-1;
            else
                b=m+1;
        }
        else{
            if(sol==caut && sol2<caut)
                return m;
            if(sol<caut)
                b=m+1;
            else
                e=m-1;
        }
    }
}
void Query(int L, int C)
{
    for(int j=1;j<=L;++j)
        for(int k=1;k<=C;++k)
            add(mat[j][k],1);
    for(int i=1;i<=n-L+1;++i)
    {
        if(i&1){
            for(int p=C;p<=m;++p)
            {
                int min1=Bin_Search(0);
                int max1=Bin_Search(L*C);
                if(max1-min1<minm)
                    minm=max1-min1,nr=1;
                else
                    if(max1-min1==minm)
                        ++nr;
                if(p<m)
                    for(int Z=i;Z<i+L;++Z){
                        add(mat[Z][p-C+1],-1);
                        add(mat[Z][p+1],1);
                    }
            }
            for(int j=m-C+1;j<=m;++j){
                add(mat[i][j],-1);
                if(i+L<=n)
                    add(mat[i+L][j],1);
            }
        }
        else
        {
            for(int p=m;p>=C;--p)
            {
                int min1=Bin_Search(0);
                int max1=Bin_Search(L*C);
                if(max1-min1<minm)
                    minm=max1-min1,nr=1;
                else
                    if(max1-min1==minm)
                        ++nr;
                if(p>C)
                    for(int Z=i;Z<i+L;++Z){
                        add(mat[Z][p],-1);
                        if(p-C>0)
                            add(mat[Z][p-C],1);
                    }
            }
            for(int j=1;j<=C;++j){
                if(i+L<=n)
                    add(mat[i+L][j],1);
                add(mat[i][j],-1);
            }
        }
    }
}
int main()
{
    f>>n>>m>>q;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            f>>mat[i][j],++mat[i][j];
    for(int i=1;i<=q;++i)
    {
        int L,C;
        f>>L>>C;
        minm=1e9;
        nr=0;
        Query(L,C);
        memset(aib,0,sizeof(aib));
        if(L!=C){
            Query(C,L);
            memset(aib,0,sizeof(aib));
        }
        g<<minm<<" "<<nr<<'\n';
    }
    return 0;
}