Cod sursa(job #467264)

Utilizator freak93Adrian Budau freak93 Data 28 iunie 2010 13:40:24
Problema Cadrane Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 2.9 kb
#include<fstream>
#include<algorithm>

using namespace std;

const char iname[]="cadrane.in";
const char oname[]="cadrane.out";
const int maxn=100005;

ifstream f(iname);
ofstream g(oname);

struct punct
{
    int x,y;
}a[maxn],arb_drept[maxn*4],arb_stang[maxn*4];

bool operator<(const punct& a,const punct& b)
{
    return a.x<b.x;
}

bool fcomp(int x,int y)
{
    return a[x].y<a[y].y;
}

int n,i,j,k,p,pos[maxn],w[maxn],maxt;

int aib_stang[maxn],aib_drept[maxn],first[maxn],last[maxn];

void update(int *aib,int x,int y)
{
    for(;x<=n;x+=(x&-x))
        aib[x]+=y;
}

int query(int *aib,int x,int y)
{
    --x;
    int s=0;
    for(;y;y-=(y&-y))
        s+=aib[y];
    for(;x;x-=(x&-x))
        s-=aib[x];
    return s;
}

int query(punct *arb)
{
    return arb[1].x+arb[1].y;
}

void update(punct *arb,int nod,int left,int right,int start, int finish,int value)
{
    if(start<=left&&right<=finish)
    {
        arb[nod].x+=value;
        return;
    }
    int mid=(left+right)>>1;
    arb[nod*2].x+=arb[nod].x;
    arb[nod*2+1].x+=arb[nod].x;
    arb[nod].x=0;
    if(start<=mid)
        update(arb,nod*2,left,mid,start,finish,value);
    if(mid<finish)
        update(arb,nod*2+1,mid+1,right,start,finish,value);

    arb[nod].y=min(arb[nod*2].x+arb[nod*2].y,arb[nod*2+1].x+arb[nod*2+1].y);
}

int main()
{
    f>>n;
    for(i=1;i<=n;++i)
        f>>a[i].x>>a[i].y;
    for(i=1;i<=n;++i)
        pos[i]=i;
    sort(a+1,a+n+1);
    sort(pos+1,pos+n+1,fcomp);
    for(i=1;i<=n;++i)
        w[pos[i]]=i;

    for(i=1;i<=n;++i)
    {
        k=1;
        j=i;
        while(i<n&&a[pos[i]].y==a[pos[i+1]].y)
            ++k,++i;
        update(arb_drept,1,1,n,j,i,k+n-i);
        k=j;
        for(;j<=i;++j)
            first[j]=k,last[j]=i,update(aib_drept,j,1);
    }
    update(arb_stang,1,1,n,1,n,n+5);

    for(i=1;i<=n;++i)
    {
        j=i;
        while(i<n&&a[i].x==a[i+1].x)
            ++i;
        for(k=j;k<=i;++k)
        {
            update(arb_stang,1,1,n,1,n,1);
            if(first[w[k]]>1)
                update(arb_stang,1,1,n,1,first[w[k]]-1,-2);
            int add=-1;
            add+=query(aib_stang,1,last[w[k]]);
            add+=query(aib_drept,first[w[k]],n);
            update(arb_stang,1,1,n,w[k],w[k],add-n-5);
            //bun pana aici sper

            /*if(first[w[k]]>1)
                update(arb_drept,1,1,n,1,first[w[k]]-1,-1);*/
            if(last[w[k]]<=n)
                update(arb_drept,1,1,n,first[w[k]],n,1);
            update(arb_drept,1,1,n,w[k],w[k],n+5);

            update(aib_stang,w[k],1);
            update(aib_drept,w[k],-1);
        }
        for(k=j;k<=i;++k)
        {
            int rez=min(query(arb_stang),query(arb_drept));
            maxt=max(maxt,rez);
        }
        for(k=j;k<=i;++k)
        {
            if(first[w[k]]>1)
                update(arb_drept,1,1,n,1,first[w[k]]-1,-1);
            update(arb_drept,1,1,n,first[w[k]],last[w[k]],-1);
        }
    }

    g<<maxt<<"\n";
}