Solution Set -「CF 1490」

cirnovsky /

☆ 「CF 1490A」Dense Array

Link.

显然不满足的 adjacent elements 之间一直加 min×2,min×4,,min×2k\min\times2,\min\times4,\cdots,\min\times2^{k},满足 min×2kmax\min\times2^{k}\le\max 即可。

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int t,n,a[60],ans;
bool judge(double one,double ano)
{
	return max(one,ano)/min(one,ano)<=2.0;
}
int jump(int one,int ano)
{
	int cone=min(one,ano),cano=max(one,ano),res=0;
	while(cone<=cano)
	{
		if((cone<<1)>=cano)	break;
		else
		{
			cone<<=1;
			res++;
		}
	}
	return res;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		ans=0;
		scanf("%d",&n);
		for(int i=1;i<=n;++i)	scanf("%d",&a[i]);
		for(int i=2;i<=n;++i)	ans+=judge(a[i],a[i-1])?0:jump(a[i],a[i-1]);
		printf("%d\n",ans);
	}
	return 0;
}

☆ 「CF 1490B」Balanced Remainders

Link.

把原序列的 c02c_{0\sim2} 统计出来然后贪心(具体怎么贪看代码,不好描述)模拟。

#include<cstdio>
#include<algorithm>
using namespace std;
int t,n,a[30010],c[3],ans;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
			++c[a[i]%3];
		}
		while((c[0]^c[1])||(c[0]^c[2]))
		{
			ans++;
			if(c[0]==*max_element(c,c+3))
			{
				--c[0];
				++c[1];
			}
			else if(c[1]==*max_element(c,c+3))
			{
				--c[1];
				++c[2];
			}
			else
			{
				--c[2];
				++c[0];
			}
		}
		printf("%d\n",ans);
		for(int i=0;i<3;++i)	c[i]=0;
		ans=0;
	}
	return 0;
}

☆ 「CF 1490C」Sum of Cubes

Link.

枚举一个 aa,然后判断 na3n-a^{3} 是否为完全立方数即可,这个可以二分,注意二分的范围不要乱搞,容易溢出。

#include<cmath>
#include<cstdio>
using namespace std;
int t,flag;
long long n;
long long cud(long long x)
{
	return x*x*x;
}
bool check(long long x)
{
	long long l=1,r=pow(x,1.0/3.0)+5;
	while(l<=r)
	{
		long long mid=(l+r)>>1;
		if(cud(mid)>x)	r=mid-1;
		else if(cud(mid)<x)	l=mid+1;
		else	return true;
	}
	return false;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		flag=0;
		scanf("%lld",&n);
		for(int i=1;cud(i)<n;++i)
		{
			if(check(n-cud(i)))
			{
				flag=1;
				break;
			}
		}
		if(flag)	printf("YES\n");
		else	printf("NO\n");
	}
	return 0;
}

☆ 「CF 1490D」Permutation Transformation

Link.

递归建树,照题意模拟即可。

#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
vector<int> e[110];
int t,n,a[110],dep[110];
int build(int l,int r)
{
	if(l>r)	return -1;
	int root=0,pos=0;
	for(int i=l;i<=r;++i)
	{
		if(a[i]>root)
		{
			root=a[i];
			pos=i;
		}
	}
	if(l^r)
	{
		int one=build(l,pos-1),ano=build(pos+1,r);
		if(~one)	e[root].push_back(one);
		if(~ano)	e[root].push_back(ano);
		return root;
	}
	else	return root;
}
void dfs(int x)
{
	for(int i=0;i<e[x].size();++i)
	{
		int y=e[x][i];
		dep[y]=dep[x]+1;
		dfs(y);
	}
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)	scanf("%d",&a[i]);
		dfs(build(1,n));
		for(int i=1;i<=n;++i)	printf("%d ",dep[a[i]]);
		printf("\n");
		for(int i=1;i<=n;++i)
		{
			dep[i]=0;
			e[i].clear();
		}
	}
	return 0;
}

☆ 「CF 1490E」Accidental Victory

Link.

贪心,记录个 id 后排序(看代码吧)。

#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
vector<int> ans;
pair<long long,int> a[200010];
int t,n;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
		{
			scanf("%lld",&a[i].first);
			a[i].second=i;
		}
		sort(a+1,a+n+1);
		for(int i=1;i<=n;++i)	a[i].first+=a[i-1].first;
		ans.push_back(a[n].second);
		for(int i=n-1;i>=1;--i)
		{
			if(a[i].first>=a[i+1].first-a[i].first)	ans.push_back(a[i].second);
			else	break;
		}
		sort(ans.begin(),ans.end());
		printf("%d\n",(int)ans.size());
		for(int i=0;i<ans.size();++i)	printf("%d ",ans[i]);
		printf("\n");
		ans.clear();
		for(int i=1;i<=n;++i)	a[i]=make_pair(0,0);
	}
	return 0;
}

☆ 「CF 1490F」Equalize the Array

Link.

统计出现次数和出现次数的出现次数,然后根号模拟取 min\min

#include<map>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=1e9;
map<int,int> one,ano;
int t,n,a[200010],ans;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&a[i]);
			++one[a[i]];
		}
		for(map<int,int>::iterator now=one.begin();now!=one.end();++now)	++ano[now->second];
		ans=INF;
		int l=0,r=n,c=one.size();
		for(map<int,int>::iterator now=ano.begin();now!=ano.end();++now)
		{
			ans=min(ans,l+r-c*now->first);
			l+=now->first*now->second;
			r-=now->first*now->second;
			c-=now->second;
		}
		printf("%d\n",ans);
		one.clear();
		ano.clear();
	}
	return 0;
}

☆ 「CF 1490G」Old Floppy Drive

Link.

denote for SS of the sum of all elements,for prepre of the prefix sum of the origin sequence。

首先判断原 prepre 里面有没有 xx,这个搞个 std::map 就有了。

when S0\andmax{prei}<xS\le0\and\max\{pre_{i}\}<x the answer doesn't exist.

if S0\and∄i,s.t.prei=xS\ge0\and\not\exists i,s.t.pre_{i}=x:此时先把 x:=xmodSx:=x\bmod S,然后就查 std::map

但是你会发现这样做写起来非常麻烦,可能需要手写平衡树。

于是你发现读错了题,是 x\ge x 不是 =x=x (日你 horse)。

然后负数直接不存进 prepre 然后开两个 std::vector 二分就好了。

#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
const long long INF=1e18;
vector<long long> onepre;
vector<int> anopre;
long long x,S,mx,len;
int t,n,m;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		mx=-INF;
		S=0;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=n;++i)
		{
			scanf("%lld",&x);
			S+=x;
			if(onepre.empty()||S>*(prev(onepre.end())))
			{
				onepre.push_back(S);
				anopre.push_back(i-1);
			}
			mx=max(S,mx);
		}
//		printf("-------------------------\n");
//		printf("onemp area:\n");
//		for(auto now:onemp)
//		{
//			printf("    preval=%lld ; preval appearing position=",now.first);
//			for(auto won:now.second)	printf("%d ",won);
//			printf("\n");
//		}
//		printf("\nanomp area:\n");
//		for(auto now:anomp)
//		{
//			printf("[preval=%lld boolean=%d]\n",now.first,now.second);
//		}
//		printf("-------------------------\n");
		while(m--)
		{
//			int minuser=0;
			scanf("%lld",&x);
			if(lower_bound(onepre.begin(),onepre.end(),x)!=onepre.end())	printf("%d ",anopre[lower_bound(onepre.begin(),onepre.end(),x)-onepre.begin()]);
			else if(S<=0)	printf("-1 ");
			else
			{
//				minuser=((x%S)==0);
				len=(mx<x)?((x-mx+S-1)/S):0;
//				printf("(%lld %lld %lld %lld)",x,S,x%S,x/S);
				printf("%lld ",(lower_bound(onepre.begin(),onepre.end(),x%S)==onepre.end())?(-1):(len*n+anopre[lower_bound(onepre.begin(),onepre.end(),x-len*S)-onepre.begin()])/*((((x%S)==0)?(0):(anopre[lower_bound(onepre.begin(),onepre.end(),x%S)-onepre.begin()]))+(int)(x/S)*len-minuser)*/);
			}
		}
		printf("\n");
		onepre.clear();
		anopre.clear();
	}
	return 0;
}