Cod sursa(job #1826442)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 10 decembrie 2016 14:40:23
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MaxN 100005
#define INF 2140000000
#define MAX 131072
using namespace std;
 
FILE *IN,*OUT;
 
int N,M,Len,cnt[MaxN],T[4*MaxN],v1[MaxN],v2[MaxN],P[MaxN],L2[MaxN],L1[MaxN],Pos,Val,pos=0,out=0;
struct Something
{
	int val,p;
	bool operator<(const Something &a)const
	{
		return val<a.val;
	}
}aux[MaxN],aux2[MaxN];

char f[MAX],Out[MAX],str[10];
inline void Write_Ch(char ch)
{
    Out[out++]=ch;
    if(out==MAX)
        fwrite(Out,MAX,1,OUT),out=0;
}
inline void Write_Int(int nr)
{
    int x=0;
    do
    {
        str[x++]=nr%10+'0';
        nr/=10;
    }
    while(nr);
    while(x>0)
        Write_Ch(str[--x]);
}
inline void Read(int &nr)
{
    nr=0;
    while(f[pos]<'0'||f[pos]>'9')
    {
        pos++;
        if(pos==MAX)
            fread(f,MAX,1,IN),pos=0;
    }
    while(f[pos]>='0'&&f[pos]<='9')
    {
        nr=10*nr+f[pos++]-'0';
        if(pos==MAX)
            fread(f,MAX,1,IN),pos=0;
    }
}

inline int Search(int val)
{
	int lw=1,hi=M,mid;

	while(lw<=hi)
	{
		mid=(lw+hi)>>1;

		if(aux[mid].val>val)
			hi=mid-1;
		else if(aux[mid].val<val)
			lw=mid+1;
		else return aux[mid].p;
	}
	return -1;
}
inline int Search2(int val)
{
	int lw=1,hi=N,mid;

	while(lw<=hi)
	{
		mid=(lw+hi)>>1;

		if(aux2[mid].val>val)
			hi=mid-1;
		else if(aux2[mid].val<val)
			lw=mid+1;
		else return aux2[mid].p;
	}
	return -1;
}
void Query(int node,int start,int end)
{
	if(Pos<=start)
		Val=max(Val,T[node]);
	else
	{
		int mid=(start+end)>>1;
		if(mid>=Pos)Query(2*node,start,mid);
		Query(2*node+1,mid+1,end);
	}
}
void Update(int node,int start,int end)
{
	if(start==end)
		T[node]=Val;
	else
	{
		int mid=(start+end)>>1;
		if(mid>=Pos)Update(2*node,start,mid);
		else Update(2*node+1,mid+1,end);
		T[node]=max(T[2*node],T[2*node+1]);
	}
}
inline void Get_L()
{
	for(int i=N;i>0;i--)
	{
		if(P[i]==-1)Val=0,cnt[0]++;
		else
		{
			Pos=P[i]+1;
			Val=0;
			Query(1,1,M);
			L1[i]=1+Val;
			cnt[L1[i]]++;
			Val=L1[i];
			Pos=P[i];
			Update(1,1,M);
			Len=max(Len,L1[i]);
			L2[Search(v1[i])]=L1[i];
		}
	}
}
inline void Reconstruct()
{
	int act=Len,p1=1,p2=1;
	for(int i=1;i<=N+M-Len;i++)
	{
		if(v1[p1]==v2[p2])
		{
			act--;
			Write_Int(v1[p1]),Write_Ch(' ');
			cnt[L1[p1]]--;
			p1++,p2++;
		}
		else if(v1[p1]<v2[p2])
		{
			if(L1[p1]==0)
			{
				cnt[L1[p1]]--,Write_Int(v1[p1++]),Write_Ch(' ');
				continue;
			}
			if(L1[p1]!=act||(L1[p1]==act&&cnt[L1[p1]]>1))
				cnt[L1[p1]]--,L2[Search(v1[p1])]=0,Write_Int(v1[p1++]),Write_Ch(' '),cnt[0]++;
			else cnt[L2[p2]]--,L1[Search2(v2[p2])]=0,Write_Int(v2[p2++]),Write_Ch(' '),cnt[0]++;
		}
		else
		{
			if(L2[p2]==0)
			{
				cnt[L2[p2]]--,Write_Int(v2[p2++]),Write_Ch(' ');
				continue;
			}
			if(L2[p2]!=act||(L2[p2]==act&&cnt[L2[p2]]>1))
				cnt[L2[p2]]--,L1[Search2(v2[p2])]=0,Write_Int(v2[p2++]),Write_Ch(' '),cnt[0]++;
			else cnt[L1[p1]]--,L2[Search(v1[p1])]=0,Write_Int(v1[p1++]),Write_Ch(' '),cnt[0]++;
		}
	}
}

int main()
{
    IN=fopen("compunere.in","r");
    OUT=fopen("compunere.out","w");

    fread(f,1,MAX,IN);

	Read(N),Read(M);
	
	for(int i=1;i<=N;i++)
		Read(v1[i]),aux2[i].p=i,aux2[i].val=v1[i];
    sort(aux2+1,aux2+1+N);
	for(int i=1;i<=M;i++)
		Read(v2[i]),aux[i].p=i,aux[i].val=v2[i];
    sort(aux+1,aux+1+M);
	for(int i=1;i<=N;i++)
		P[i]=Search(v1[i]);

	Get_L();

	Write_Int(M+N-Len),Write_Ch('\n');

	v1[N+1]=INF;
	v2[M+1]=INF;

	Reconstruct();
	
    if(out>0)fwrite(Out,1,out,OUT);

	return 0;
}