CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes)

本文解析了五道算法竞赛题目,包括寻找符合条件的好对、判断序列操作的可能性、使数组元素相等的操作、寻找特定形式的表达式以及构造树的权重等。通过对每道题目的深入分析,提供了详细的解题思路和实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A Good Pairs

You are given an array a1,a2,…,ana_1,a_2,…,a_na1,a2,,an of positive integers. A good pair is a pair of indices (i,j)(i,j)(i,j) with 1≤i,j≤n1≤i,j≤n1i,jn such that, for all 1≤k≤n1≤k≤n1kn, the following equality holds:
∣ai−ak∣+∣ak−aj∣=∣ai−aj∣|ai−ak|+|ak−aj|=|ai−aj|aiak+akaj=aiaj
where ∣x∣|x|x denotes the absolute value of xxx.

Find a good pair. Note that iii can be equal to jjj.

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
pair<int,int> a[112345];
int main()
{
//	freopen("A.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--) {
		int n=read();
		For(i,n) a[i]=mp(read(),i);
		sort(a+1,a+1+n);
		cout<<a[1].se<<' '<<a[n].se<<endl;
	}
	
	
	return 0;
}

B Subtract Operation

You are given a list of n integers. You can perform the following operation: you choose an element x from the list, erase x from the list, and subtract the value of x from all the remaining elements. Thus, in one operation, the length of the list is decreased by exactly 1.

Given an integer k (k>0), find if there is some sequence of n−1 operations such that, after applying the operations, the only remaining element of the list is equal to k.

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
set<ll> h;
int work() {
	ll n=read(),k=read();
	h.clear();
	bool b=0;
	while(n--) {
		ll a=read();
        if ( h.find(a-k)!=h.end() || h.find(a+k)!=h.end() ) {
        	b=1;
        };
        h.insert(a);
    }
    return b;
}
int main()
{
//	freopen("A.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--) {
        puts(work()?"YES":"NO");
	}
	return 0;
}

C Make Equal With Mod

You are given an array of n non-negative integers a1,a2,…,an. You can make the following operation: choose an integer x≥2 and replace each number of the array by the remainder when dividing that number by x, that is, for all 1≤i≤n set ai to aimodx.

Determine if it is possible to make all the elements of the array equal by applying the operation zero or more times.

考虑ai mod ai=0a_i \bmod a_i =0aimodai=0,所以想办法把所有数变成0,发现有1的情况不行,1不能变成其它数

分类讨论:

  1. 没有1,全变成0
  2. 有1,全变成1
    情况2需要ai mod (ai−1)=1a_i \bmod (a_i-1) =1aimod(ai1)=1,因此不能出现相邻的数,不能出现0,20,20,2
#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
int a[112345];
void work() {
		int n=read();
	For(i,n) a[i]=read();
	sort(a+1,a+1+n);
	int fl1=0;
	For(i,n) if(a[i]==1) fl1++;
	if(!fl1) puts("YES");
	else {
		For(i,n)
		if(a[i]==0||a[i]==2||(a[i]>=3&&i<n && a[i+1]==a[i]+1)) {
			puts("NO");
			return;
		}
		puts("YES");
	}
}
int main()
{
//	freopen("A.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--) {
		work();
	}
	
	
	return 0;
}

D K-good

We say that a positive integer n is k-good for some positive integer k if n can be expressed as a sum of k positive integers which give k distinct remainders when divided by k.

Given a positive integer n, find some k≥2 so that n is k-good or tell that such a k does not exist.

k+(k+1)+⋯+(k+k−1)+tk=k(k−1)/2+tk(t≥0,t∈Z)k+(k+1)+\cdots + (k+k-1)+tk=k(k-1)/2+tk(t\ge 0,t\in Z)k+(k+1)++(k+k1)+tk=k(k1)/2+tk(t0,tZ)
因此当k是奇数时,k是n的因子
k是偶数的情况可以覆盖所有>=3的奇数的情况

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long long ll;
const int maxp = 1e6 + 1, maxv = 25, maxc = (int)1e4 + 1;
int ptot, pr[maxp], d[maxp], cnt;
LL n, p[maxc];
LL mod_add(LL x, LL y, LL p) {
	return (x += y) < p ? x : x - p;
}
LL mod_mul(LL x, LL y, LL p) {
	LL ret = x * y - (LL)((long double)x * y / p + 0.5) * p;
	return ret < 0 ? ret + p : ret;
}
LL mod_pow(LL x, LL k, LL p) {
	LL ret = 1 % p;
	for( ; k > 0; k >>= 1, x = mod_mul(x, x, p))
		(k & 1) && (ret = mod_mul(ret, x, p));
	return ret;
}
bool miller_rabin(LL n) {
	if(n == 2) return 1;
	if(n < 2 || !(n & 1))
		return 0;
	LL s = 0, r = n - 1;
	for( ; !(r & 1); r >>= 1, ++s);
	for(int i = 0; pr[i] < n && pr[i] < maxv; ++i) {
		LL cur = mod_pow(pr[i], r, n), nxt;
		for(int j = 0; j < s; ++j) {
			nxt = mod_mul(cur, cur, n);
			if(nxt == 1 && cur != 1 && cur != n - 1) return 0;
			cur = nxt;
		}
		if(cur != 1) return 0;
	}
	return 1;
}
LL gcd(LL a, LL b) {
	int ret = 0;
	while(a) {
		for( ; !(a & 1) && !(b & 1); ++ret, a >>= 1, b >>= 1);
		for( ; !(a & 1); a >>= 1);
		for( ; !(b & 1); b >>= 1);
		if(a < b)
			swap(a, b);
		a -= b;
	}
	return b << ret;
}
LL pollard_rho(LL n) {
	static LL seq[maxp];
	while(1) {
		LL x = rand() % n, y = x, c = rand() % n;
		LL *px = seq, *py = seq, tim = 0, prd = 1;
		while(1) {
			*py++ = y = mod_add(mod_mul(y, y, n), c, n);
			*py++ = y = mod_add(mod_mul(y, y, n), c, n);
			if((x = *px++) == y) break;
			LL tmp = prd;
			prd = mod_mul(prd, abs(y - x), n);
			if(!prd) return gcd(tmp, n);
			if((++tim) == maxv) {
				if((prd = gcd(prd, n)) > 1 && prd < n) return prd;
				tim = 0;
			}
		}
		if(tim && (prd = gcd(prd, n)) > 1 && prd < n) return prd;
	}
}
void decompose(LL n) {
	for(int i = 0; i < cnt; ++i)
		if(n % p[i] == 0) {
			p[cnt++] = p[i];
			n /= p[i];
		}
	if(n < maxp) {
		for( ; n > 1; p[cnt++] = d[n], n /= d[n]);
	} else if(miller_rabin(n)) {
		p[cnt++] = n;
	} else {
		LL fact = pollard_rho(n);
		decompose(fact), decompose(n / fact);
	}
} // prepare pr(prime) and d(minimal factor)
map<LL,int> h;
ll xs[3000];
ll xs2[3000];
vector<vector<LL> > table;
int main() {
	for(int i = 2; i < maxp; ++i) {
		if(!d[i])
			pr[ptot++] = d[i] = i;
		for(int j = 0, k; (k = i * pr[j]) < maxp; ++j) {
			d[k] = pr[j];
			if(d[i] == pr[j])
				break;
		}
	}
	int m, mod = 1000000007;
	int T;cin>>T;
	while(T--) {
		cnt=0;
		LL n;
		cin>>n;
		LL n2=n;
		LL b = n;
		int a = 0;
		LL pa = 1;
	    while ((b & 1) == 0) {
	        b /= 2;
			pa *= 2;
	    }
	    pa *= 2;
	    if (pa + 1 <= b) {
			cout<<pa<<endl; continue;
		}
		decompose(n);
		sort(p, p + cnt);
		ll ans=-1;
		for(int i=0;i<cnt;i++) if(p[i]!=2){
			bool fl=2.0*n2/p[i]>=(p[i]-1);
			if (fl) {
				ans=p[i];break;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

E Equal Tree Sums

You are given an undirected unrooted tree, i.e. a connected undirected graph without cycles.

You must assign a nonzero integer weight to each vertex so that the following is satisfied: if any vertex of the tree is removed, then each of the remaining connected components has the same sum of weights in its vertices.

 #include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i>0;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,cal) printf("Case #%d: %lld\n",kcase,cal);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define add(a,b) ((a+b)%F)
ll mul(ll a,ll b){return (a*b)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 

#define MAXN (212345)
ll n;
vi v[MAXN];
int ans[MAXN];
void dfs(int x,int fa,int fl) {
	ans[x]=v[x].size();
	if(fl)ans[x]*=-1;
	for (auto u:v[x])
		if (u!=fa) {
			dfs(u,x,fl^1);
	}
}
int main()
{
//	freopen("c.in","r",stdin);
//	freopen(".out",w",stdout);
	int T=read();
	while(T--) {
		n=read();
		For(i,n-1) {
			int x=read(),y=read();
			v[x].pb(y); v[y].pb(x);
		}
		dfs(1,-1,1);
		For(i,n) v[i].resize(0);
		PRi(ans,n)
	}
	return 0;
}


F Parametric MST

You are given nnn integers a1,a2,…,ana1,a2,…,ana1,a2,,an. For any real number t, consider the complete weighted graph on nnn vertices Kn(t)Kn(t)Kn(t) with weight of the edge between vertices iii and jjj equal to wij(t)=ai⋅aj+t⋅(ai+aj)w_{ij}(t)=a_i⋅a_j+t⋅(a_i+a_j)wij(t)=aiaj+t(ai+aj).

Let f(t)f(t)f(t) be the cost of the minimum spanning tree of Kn(t)Kn(t)Kn(t). Determine whether f(t)f(t)f(t) is bounded above and, if so, output the maximum value it attains.

Input
The input consists of multiple test cases. The first line contains a single integer T(1≤T≤104)T (1≤T≤10^4)T(1T104) — the number of test cases. Description of the test cases follows.

The first line of each test case contains an integer n(2≤n≤2⋅105)n (2≤n≤2⋅10^5)n(2n2105) — the number of vertices of the graph.

The second line of each test case contains nnn integers a1,a2,…,an(−106≤ai≤106)a_1,a_2,…,a_n (−10^6 ≤ai≤ 10^6)a1,a2,,an(106ai106).

The sum of n for all test cases is at most 2⋅1052⋅10^52105.

Output
For each test case, print a single line with the maximum value of f(t)f(t)f(t) (it can be shown that it is an integer), or INF if f(t)f(t)f(t) is not bounded above.

Example
inputCopy
5
2
1 0
2
-1 1
3
1 -1 -2
3
3 -1 -2
4
1 2 3 -4
outputCopy
INF
-1
INF
-6
-18

w(i,j)=wij(t)=ai⋅aj+t⋅(ai+aj)=(ai+t)(aj+t)−t2w(i,j)=w_{ij}(t)=a_i⋅a_j+t⋅(a_i+a_j) = (a_i+t)(a_j+t)-t^2w(i,j)=wij(t)=aiaj+t(ai+aj)=(ai+t)(aj+t)t2
考虑最小生成树,对于点iii而言,当ai+t<0a_i+t<0ai+t<0时连aj+ta_j+taj+t最大的,当ai+t>0a_i+t>0ai+t>0时连aj+ta_j+taj+t最小的,当ai+t=0a_i+t=0ai+t=0时连任意一个。

最后考察当ttt为正、负无穷时,最小生成树边权和是否为正无穷即可。

 #include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i>0;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,cal) printf("Case #%d: %lld\n",kcase,cal);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define add(a,b) ((a+b)%F)
ll mul(ll a,ll b){return (a*b)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 

#define MAXN (212345)
ll n;
ll a[MAXN];
bool fl=0;
ll work() {
	ll ans=-1e18;
	sort(a+1,a+1+n);
	ll B=0,K=0;
	Fork(i,2,n) K+=a[1]+a[i];
	if(K>0){ // means no upbound when t=+oo
		fl=1;return 0;
	} 
	K=0;
	For(i,n-1) K+=a[i]+a[n];
	if(K<0) {// means no upbound when t=-oo
		fl=1;return 0;
	}
	
	K=0;	
	Fork(i,2,n) K+=a[1]+a[i],B+=a[1]*a[i];
	// 1-n 2-n k-n 1-(k+1) 1-n-1
		
	gmax(ans,K*max(-a[1],-a[n])+B);
	
	Fork(i,2,n-1) {
		K+=-a[1]+a[n];B+=-a[1]*a[i]+a[i]*a[n];
		gmax(ans,K*(-a[i+1])+B);
		gmax(ans,K*(-a[i])+B);
	}
	return ans;	
}
int main()
{
//	freopen("c.in","r",stdin);
//	freopen(".out",w",stdout);
	int T=read();
	while(T--) {
		n=read();
		For(i,n) a[i]=read();
		fl=0;
		ll t=work();
		if(fl) puts("INF");else cout<<t<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值