Cod sursa(job #1247665)

Utilizator ZenusTudor Costin Razvan Zenus Data 23 octombrie 2014 10:26:08
Problema Felinare Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.22 kb
#include <cstdio>
#include <vector>
#include <set>

using namespace std;

#define S second
#define F first
#define NMAX 9000

pair < int , pair < int , int > > T[4*NMAX];
int Gi[NMAX],Ge[NMAX];
set < pair < int , int > > w;
vector < int > :: iterator u;
vector < int > G[2][NMAX];
int i,N,M,X,Y,left;
pair < bool , bool > marked[NMAX];

void Build(int node,int left,int right,int where,pair < int , pair < int , int > > e)
{
    if (!(left<=where && where<=right))
    return ;

    if (left==where && where==right)
    {
        T[node]=e;
        return ;
    }

    int mid=(left+right)>>1;
    Build(2*node,left,mid,where,e);
    Build(2*node+1,mid+1,right,where,e);

    if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
    T[node]=T[2*node];
    else T[node]=T[2*node+1];
}

void Update(int node,int left,int right,int where,bool flag)
{
    if (!(left<=where && where<=right))
    return ;

    if (left==where && where==right)
    {
        (!flag) ? --T[node].S.F : --T[node].S.S;
        return ;
    }

    int mid=(left+right)>>1;
    Update(2*node,left,mid,where,flag);
    Update(2*node+1,mid+1,right,where,flag);

    if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
    T[node]=T[2*node];
    else T[node]=T[2*node+1];
}

void Update_all(int node,int left,int right,int where,bool flag)
{
    if (!(left<=where && where<=right))
    return ;

    if (left==where && where==right)
    {
        (!flag) ? T[node].S.F=0 : T[node].S.S=0;
        return ;
    }

    int mid=(left+right)>>1;
    Update(2*node,left,mid,where,flag);
    Update(2*node+1,mid+1,right,where,flag);

    if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
    T[node]=T[2*node];
    else T[node]=T[2*node+1];
}

int main()
{
freopen("felinare.in","r",stdin);
freopen("felinare.out","w",stdout);

for (i=1,scanf("%d%d",&N,&M);i<=M;++i)
{
    scanf("%d%d",&X,&Y);
    ++Ge[X];
    ++Gi[Y];

    G[0][X].push_back(Y);
    G[1][Y].push_back(X);

    w.insert(make_pair(X,Y));
}

for (i=1;i<=N;++i)
{
    marked[i]=make_pair(true,true);
    Build(1,1,N,i,make_pair(i,make_pair(Ge[i],Gi[i])));
}

while (!w.empty())
{
    if (T[1].S.F>=T[1].S.S)
    {
        for (u=G[0][T[1].F].begin();u!=G[0][T[1].F].end();++u)
        {
            if (w.find(make_pair(T[1].F,*u))!=w.end())
            w.erase(w.find(make_pair(T[1].F,*u)));

            Update(1,1,N,*u,true);
        }

        marked[T[1].F].F=false;
        Update_all(1,1,N,T[1].F,false);

        continue;
    }

    for (u=G[1][T[1].F].begin();u!=G[1][T[1].F].end();++u)
    {
        if (w.find(make_pair(*u,T[1].F))!=w.end())
        w.erase(w.find(make_pair(*u,T[1].F)));

        Update(1,1,N,*u,true);
    }

    marked[T[1].F].S=false;
    Update_all(1,1,N,T[1].F,true);
}

for (i=1;i<=N;++i)
left+=(!marked[i].F+!marked[i].S);

for (i=1,printf("%d\n",2*N-left);i<=N;++i)
{
    if (marked[i].F && marked[i].S)
    printf("3\n");

    if (!marked[i].F && marked[i].S)
    printf("2\n");

    if (marked[i].F && !marked[i].S)
    printf("1\n");

    if (!marked[i].F && !marked[i].S)
    printf("0\n");
}

return 0;
}