bzoj 4386 [POI2015] Tours

bzoj 4386 [POI2015] Tours

This question of what qualities, even if a long long burst, even int128 have burst ...... finally had a long double card ...... but I may be right itself comes with a large constant, T for a long time ......

Let me talk about super Meeting Point count it, start with the conclusion:

1. All points (only one point in this question) to one side of super sink even 0, the matrix multiplication n times, the corresponding F [i] [j] number from i to j take the solution as the steps n , F [i] [0] to the number of programs is i 0 n walking steps, if the ans him by a matrix (first ans), the f [0] [0] -n (dots) length is equal for all program path number (index) n. 0 ans matrix side connected to all other points.

2. If, at 1, even want to own the 0 side, the multiplication will be accumulated each time, ultimately resulting length is the number of all possible routes to n or less.

Specific can be understood:

After ans matrix corresponds to the point of departure from the super-exchange step, a base matrix multiply each, equivalent to go one step further, take n times, the equivalent of walking n steps, but still have to take a base, equivalent to the points back to 0 , while the counter still retains a number from 0 out program, in which case f [0] [0] - the number of points is the answer. (This issue their own hand prints what it would be easier to understand).

Then Solution:

1,2,3 only three kinds of edge weights, consider split point (the 'lost' is also used in the same manner), a point will be divided into three, $ $, each point of the first stage to the second cascade edge, a second edge connected to the third level stage, for an a-> b, a length of the edge w, the w-th stage from a stage connected to a first edge length b is 1.get(int po,int w){return (po-1)*3+w;}

Code:

 1     for(int i=1;i<=m;i++)
 2     {
 3         a=read(),b=read(),c=read();
 4         cs.m[get(a,c)][get(b,1)]++;
 5     }    
 6     for(int i=1;i<=n;i++)
 7     {    
 8         cs.m[get(i,1)][get(i,2)]++;
 9         cs.m[get(i,2)][get(i,3)]++;
10     }
View Code

 This resulted in an initial matrix constructed ans matrix, it will be apparent half enumerated length solved, but high complexity will be T, consider multiplying advance preprocessing the initial matrix multiplication $ 2 ^ matrix after I $, as LCA as engage in it.

This question, however there are a few pit:

Multiplication program will burst when longlong (if you hit the point of nausea even __int128 will burst), can be added to determine, personal feeling is too much trouble, so he used a double, it will burst? Did not panic there are long double.

Then the T with lemon test a little, ran over one hundred seconds, but fortunately ran right , in fact, this is not a long double pot, and I own a large constant relationship is not large , pre-multiplying array when I ask him to fix the 65, resulting in a long time, in fact, you can record it:

1 for(int i=1;i<=65;i++,imax++){F[i]=F[i-1]*F[i-1];if((ans*F[i]).count()>k)break;}
View Code

 Then A, and run pretty fast. In fact, I still do not understand why so much worse, seek fixed to 65 complexity is n ^ 3log_n $ $ ah ......

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N n*3
#define LD long double
#define LL long long
using namespace std;
int n,m;LL k;
struct jz
{
	LD m[121][121];
	LD count() {return m[0][0]-n;}
}cs,ans,F[70];
jz operator * (jz &a,jz &b)
{
	jz ans;
	for(int i=0;i<=N;i++)
		for(int j=0;j<=N;j++)
			ans.m[i][j]=0;
	for(int i=0;i<=N;i++)
		for(int j=0;j<=N;j++)
			for(int k=0;k<=N;k++)
				ans.m[i][j]+=a.m[i][k]*b.m[k][j];
	return ans;
}
inline int get(const register int po,const register int w){return (po-1)*3+w;}
inline LL read()
{
	LL s=0;char a=getchar();
	while(a<'0'||a>'9')a=getchar();
	while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
	return s;
}
signed main()
{
//	freopen("10.in","r",stdin);

	n=read(),m=read(),k=read();
	int a,b,c;
	for(int i=1;i<=m;i++)
	{
		a=read(),b=read(),c=read();
		cs.m[get(a,c)][get(b,1)]++;
	}	
	for(int i=1;i<=n;i++)
	{	
		cs.m[get(i,1)][get(i,2)]++;
		cs.m[get(i,2)][get(i,3)]++;
	}
	LL imax=1;
	cs.m[0][0]=1;
	for(int i=1;i<=n;i++)cs.m[get(i,1)][0]++;
	for(int i=1;i<=n;i++)ans.m[0][get(i,1)]=1;
	F[0]=cs;
	for(int i=1;i<=65;i++,imax++){F[i]=F[i-1]*F[i-1];if((ans*F[i]).count()>k)break;}
	if((ans*F[imax]).count()<k){cout<<-1<<endl;return 0;}
	LL num=0;
	for(int i=imax;i>=0;i--)
	{
		jz tm=ans*F[i];
		if(tm.count()<k){num+=1ll<<i;ans=ans*F[i];}
	}
	cout<<num<<endl;
}

 

Guess you like

Origin www.cnblogs.com/Al-Ca/p/11203835.html