Codeforces Round #707 (Div 2)

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

A. Alexey and Train

After you understand the question, you can simulate it directly. Here I let t be the time of each departure.

#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. Napoleon Cake

From back to front, use a variable to record how many more can be poured down there, and just maintain it every time.

#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. Going Home

Remember this technique, four numbers abcd, a+d=b+c, ​​that is, ab=cd, then since 1≤ai≤2.5⋅1e6, the difference between any two numbers is at most 2.5*1e6 kinds, n numbers There are two square levels for taking two numbers, so as long as the n square level is greater than 2.5e6, it will do, that is to say, only about 5,000 of the 200,000 given numbers will do.
(It will be found that only when the number is small, there may be NO. If there are a lot of numbers (such as 5000), there must be a solution.)
As for the sorting in the program, I want to sort the numbers in the same order and squeeze them together. , Then maybe the answer comes out faster if you choose the first 5000 numbers?

#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. Two chandeliers

Because ai are not equal to each other, the different colors are considered separately.
For example, for the color colr, where a is the i-th and b is the j-th, then the point at which they meet at one time is t
t= x1*n+i = x2*m+j. Here, x1 x2 are all integers. If you deform it
x1*n-x2*m=j-i, it becomes the solution of the indeterminate equation. Let's extend gcd.
Having reached where each color is stored to first encounter sinside the array (where I do not meet -1replaced), the first encounter each color, every lcm (n, m) met only once.
After that, I used the binary answer method. The judgment condition is that for the time M, if the number of different times is greater than or equal to k, then it returns 1; otherwise, it returns 0.
This is the answer. The time complexity is O(max(n,m)*lg(k)), maybe...

#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
*/

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/114776352