Cod sursa(job #2091502)

Utilizator stefdascalescuStefan Dascalescu stefdascalescu Data 19 decembrie 2017 19:15:05
Problema Struti Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 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)
{
    if(nod==0){
        aib[0]+=val;
        nod=1;
    }
    for(;nod<=8000;nod+=(nod&(-nod)))
        aib[nod]+=val;
}
int Compute(int nod)
{
    int sol=0;
    for(;nod>0;nod-=(nod&(-nod)))
        sol+=aib[nod];
    return sol;
}
int Bin_Search(int caut)
{
    int b=0;
    int e=8000;
    while(b<=e)
    {
        int m=(b+e)/2;
        if(caut==0){
            if(Compute(m)>0 && Compute(m-1)==0)
                return m;
            if(Compute(m)>0)
                e=m-1;
            else
                b=m+1;
        }
        else{
            if(Compute(m)==caut && Compute(m-1)<caut)
                return m;
            if(Compute(m)<caut)
                b=m+1;
            else
                e=m-1;
        }
    }
}
void Query(int L, int C)
{
    for(int i=1;i<=n-L+1;++i)
    {
        for(int j=i;j<i+L;++j)
            for(int k=1;k<=C;++k)
                add(mat[j][k],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;
            for(int Z=i;Z<i+L;++Z){
                add(mat[Z][p-C+1],-1);
                if(p<m)
                    add(mat[Z][p+1],1);
            }
        }
        for(int Z=i;Z<i+L;++Z)
            for(int j=m-C+2;j<=m;++j)
                add(mat[Z][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];
    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;
}