Ronda de Codeforces # 707 (Div 2)

Enlace: https://codeforces.com/contest/1501

A. Alexey y Train

Una vez que haya entendido la pregunta, puede simularla directamente, aquí dejo la hora de cada salida.

#include <bits/stdc++.h>
using namespace std;
#define N 105

long long n,a[N],b[N],tt[N];

void solve()
{
    
    
	long long tmp;
	scanf("%lld",&n);
	for (int i=1; i<=n; i++)
		scanf("%lld%lld",&a[i],&b[i]);
	for (int i=1; i<=n; i++)
		scanf("%lld",&tt[i]);
	
	long long t=0;
	for (int i=1; i<n; i++)
	{
    
    
		tmp=t+a[i]-b[i-1]+tt[i]+(b[i]-a[i]+1)/2;
		t=max(tmp,b[i]);
	}
	
	t+=a[n]-b[n-1]+tt[n];
	
	printf("%lld\n",t);
}

int main()
{
    
    
	int t;
	scanf("%d",&t);
	while (t--)
	{
    
    
		solve();
	}
	return 0;
}

B. Pastel de Napoleón

De atrás hacia adelante, use una variable para registrar cuántas más se pueden verter allí y manténgala siempre.

#include <bits/stdc++.h>
using namespace std;

int n,a[200005],f[200005];

void solve()
{
    
    
	scanf("%d",&n);
	for (int i=1; i<=n; i++)
	{
    
    
		f[i]=0;
		scanf("%d",&a[i]);
	}
	
	int cnt=0;
	for (int i=n; i>0; i--)
	{
    
    
		cnt=max(cnt,a[i]);
		f[i]= (cnt>0);
		cnt--;
	}
	
	for (int i=1; i<=n; i++)
		printf("%d ",f[i]);
	puts("");
}

int main()
{
    
    
	int t;
	scanf("%d",&t);
	while (t--)
	{
    
    
		solve();
	}
	return 0;
}

C. Regreso a casa

Recuerde esta técnica, cuatro números abcd, a + d = b + c, es decir, ab = cd, entonces como 1≤ai≤2.5⋅1e6, la diferencia entre dos números es como máximo 2.5 * 1e6 tipos, n números Hay dos niveles cuadrados para tomar dos números, por lo que siempre que el nivel n cuadrado sea mayor que 2.5e6, será suficiente, es decir, solo alrededor de 5,000 de los 200,000 números dados serán suficientes.
(Encontrará que NO puede ocurrir solo cuando el número es pequeño. Si hay muchos números (como 5000), debe haber una solución).
En cuanto a la clasificación en el programa, quiero ordenar los números en en el mismo orden y apriételos juntos. Entonces, ¿tal vez la respuesta salga más rápido si elige los primeros 5000 números?

#include <bits/stdc++.h>
using namespace std;

int n;
int a[200005],c[200005];
vector<pair<int,int>> f[5000005];

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

#define I c[i]
#define J c[j]

void solve()
{
    
    
	scanf("%d",&n);
	for (int i=1; i<=n; i++)
	{
    
    
		scanf("%d",&a[i]);
		c[i]=i;
	}
		
	sort(c+1,c+n+1,cmp);
	
	for (int i=1,mi=min(n,5000); i<mi; i++)
	{
    
    
		for (int j=i+1; j<=mi; j++)
		{
    
    
			int sum=a[I]+a[J];
			if (!f[sum].empty())
			{
    
    
				for (auto A: f[sum])
				{
    
    
					if (A.first!=I && A.first!=J && A.second!=I && A.second!=J)
					{
    
    
						puts("YES");
						printf("%d %d %d %d\n",A.first, A.second, I,J);
						return;
					}
				}
			}
			f[sum].emplace_back(make_pair(I,J));
		}
	}
	
	puts("NO");
}

int main()
{
    
    
	solve();
	return 0;
}

D. Dos candelabros

Debido a que ai no son iguales entre sí, los diferentes colores se consideran por separado.
Por ejemplo, para el color colr, donde a es el i-ésimo y b es el j-ésimo, entonces el punto en el que se encuentran al mismo tiempo es t
t= x1*n+i = x2*m+j. Aquí, x1 x2 son todos números enteros. Si lo deforma
x1*n-x2*m=j-i, es se convierte en la solución de la ecuación indeterminada Extendamos mcd.
Habiendo llegado al lugar donde se almacena cada color para encontrarlo por primera vez sdentro de la matriz (donde no me encuentro -1reemplazado), el primer encuentro con cada color, cada lcm (n, m) se reunió solo una vez.
Después de eso, utilicé el método de respuesta binaria. La condición de juicio es que para el tiempo M, si el número de veces diferentes es mayor o igual que k, entonces devuelve 1; de lo contrario, devuelve 0.
Esta es la respuesta. La complejidad del tiempo es O (max (n, m) * lg (k)), tal vez ...

#include <bits/stdc++.h>
using namespace std;

long long n,m,k,nmgcd,nmlcm;

long long gcd(long long x, long long y){
    
    return y ? gcd(y,x%y) : x;}
long long lcm(long long x, long long y)
{
    
    
	long long tt=gcd(x,y);
	tt=x*y/tt;
	return tt;
}

long long exgcd(long long aa,long long bb,long long &x,long long &y)//扩展欧几里得算法
{
    
    
    if(bb==0)
    {
    
    
        x=1;y=0;
        return aa;  //到达递归边界开始向上一层返回
    }
    long long r=exgcd(bb,aa%bb,x,y);
    long long temp=y;    //把x y变成上一层的
    y=x-(aa/bb)*y;
    x=temp;
    return r;     //得到a b的最大公因数
}

#define N 500005

long long a[N],b[N],fa[N<<1],fb[N<<1],s[N<<1],MM;

bool check(long long x)
{
    
    
	long long cnt=x;
	for (long long i=MM; i; i--) if (s[i]>0)
	{
    
    
		if (x>=s[i])
		{
    
    
			cnt-=(x-s[i])/nmlcm+1;
		}
	}
	return cnt>=k;
}

void solve()
{
    
    
	scanf("%lld%lld%lld",&n,&m,&k);
	MM=max(n,m)<<1;
	
	
	
	for (long long i=1; i<=n; i++)
	{
    
    
		scanf("%lld",&a[i]);
		fa[a[i]]=i;
	}
	
	for (long long i=1; i<=m; i++)
	{
    
    
		scanf("%lld",&b[i]);
		fb[b[i]]=i;
	}
	
	nmgcd=gcd(n,m);
	nmlcm=lcm(n,m);
	
	for (long long colr=MM; colr; colr--)
	{
    
    		
		if (fa[colr]==0 || fb[colr]==0 || (fb[colr]-fa[colr])%nmgcd!=0)
		{
    
    
			s[colr]=-1;
			continue;
		}
		
		if (fa[colr]==fb[colr])
		{
    
    
			s[colr]=fa[colr];
			continue;
		}
		
		long long x1,x2,tmp;
		exgcd(n,m,x1,x2);
		x1*=((fb[colr]-fa[colr])/nmgcd);
		x2*=((fb[colr]-fa[colr])/nmgcd);
		tmp=x1*n+fa[colr];
		tmp=((tmp-1)%nmlcm+nmlcm)%nmlcm+1;
		s[colr]=tmp;
	}
	
	long long L=1,R=(1ll<<61),M,ans;
	for (; L<R; )
	{
    
    
		M=(L+R)>>1;
		if (check(M))
			ans=R=M;
		else
			L=M+1;
	}
	
	printf("%lld\n",ans);
}

int main()
{
    
    
	solve();
	return 0;
}

/*
3 8 41
1 3 2
1 6 4 3 5 7 2 8
*/

Supongo que te gusta

Origin blog.csdn.net/jackypigpig/article/details/114776352
Recomendado
Clasificación