Cod sursa(job #1492148)

Utilizator nickulNic Kul nickul Data 27 septembrie 2015 08:14:56
Problema Xor Max Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include<fstream>
#include<vector>
#include<list>
#include<map>
#include<iterator>

using namespace std;

struct nod
{
	nod():zero(0),unu(0){}
	size_t zero,unu;
};
vector<nod> noduri;

struct frunza
{
	frunza():val(0),poz(){}
	frunza(size_t y, size_t i):val(y),poz(1,i){}
	size_t val;
	vector<size_t> poz;
};
map<size_t,frunza> fr;

struct triplet
{
	triplet():unu(0),doi(0),trei(0){}
	triplet(size_t u, size_t d, size_t t):unu(u),doi(d),trei(t){}
	triplet(size_t u, size_t d):unu(u),doi(d),trei(fr[u].val^fr[d].val){}
	size_t unu,doi,trei;
};
list<triplet> sol;


void rez(size_t zero, size_t unu)
{
	bool ok=0;
	vector<size_t> z,u;
	if(fr.count(zero)&&fr.count(unu))
	{
		sol.push_back(triplet(unu,zero));
		return;
	}
	size_t zz=noduri[zero].zero,zu=noduri[zero].unu,uz=noduri[unu].zero,uu=noduri[unu].unu;
	if(zero==unu)
	{
		if(zz&&zu)
			{
				rez(zz,zu);
				return;
			}
		if(zz)
			rez(zz,zz);
		if(zu)
			rez(zu,zu);
		return;
	}
	if(zz&&uu)
	{
		rez(zz,uu);
		ok=1;
	}
	if(zu&&uz)
	{
		rez(zu,uz);
		ok=1;
	}
	if(ok) return;
	if(zz)
		rez(zz,uz);
	if(zu)
		rez(zu,uu);
	return;
}

ifstream in("xormax.in");
ofstream out("xormax.out");

int main()
{
	size_t n,x,y=0,i,j,k,poz=0,max=0;
	noduri.push_back(nod());
	for(k=21;k>0;k--)
	{
		noduri.push_back(nod());
		poz=noduri[poz].zero=noduri.size()-1;
	}
	fr[21].poz.push_back(0);
	fr[21].val=0;
	in>>n;
	for(i=1;i<=n;i++)
	{
		in>>x;
		y^=x;
		j=0;
		poz=0;
		while(y>>j) j++;
		for(k=21;k>0;k--)
		{
			if(y&1<<(k-1))
			{
				if(!noduri[poz].unu)
				{
					noduri.push_back(nod());
					noduri[poz].unu=noduri.size()-1;
				}
				poz=noduri[poz].unu;
			}
			else
			{
				if(!noduri[poz].zero)
				{
					noduri.push_back(nod());
					noduri[poz].zero=noduri.size()-1;
				}
				poz=noduri[poz].zero;
			}
		}
		if(fr.count(poz))
			fr[poz].poz.push_back(i);
		else
			fr.emplace(poz,frunza(y,i));
	}
	rez(0,0);
	for(list<triplet>::iterator it=sol.begin();it!=sol.end();++it)
	{
		if(max<(*it).trei)
		{
			max=(*it).trei;
			sol.erase(sol.begin(),it);
			it=sol.begin();
		}
		if(max>(*it).trei)
		{
			sol.erase(it);
			it--;
		}
	}
	out<<max<<' ';
	size_t start=n,stop=n,min1,min2;
	for(list<triplet>::iterator it=sol.begin();it!=sol.end();++it)
	{
		min1=fr[(*it).unu].poz[0];
		min2=fr[(*it).doi].poz[0];
		max=0;
		if (min1>min2) 
		{
			min1^=min2;
			min2^=min1;
			min1^=min2;
			max=1;
		}
		if(min2<stop)
		{
			stop=min2;
			start=min1;
			if(max)
			{
				for(i=1;i<fr[(*it).doi].poz.size();i++)
				{
					if(fr[(*it).doi].poz[i]>=min2) break;
					start=fr[(*it).doi].poz[i];
				}
			}
			else
			{
				for(i=1;i<fr[(*it).unu].poz.size();i++)
				{
					if(fr[(*it).unu].poz[i]>=min2) break;
					start=fr[(*it).unu].poz[i];
				}
			}
		}
	}
	out<<start+1<<' '<<((stop)?stop:stop+1);
}