CF1707B Difference Array

题目大意

题目大意非常简短,就是给你一个数组。每次同时进行 \(a_i=a_{i+1}-a_i\) 的操作,求最后留下的一个数是什么,如下:

  1. 计算数组中相邻两个元素的差值,得到新的数组。
  2. 对新数组排序,然后将其替换。
  3. 重复此过程,直到数组只剩一个元素。

题意分析

关于直接暴力模拟差分,看似时间复杂度是 \(O(n^2\log n )\) 的,但是他还就不是。我们不难发现,如果有了零的话,这个零的位置是不用排序和怎么操作或操作太多的。而且既然是求差值,后面的数两两一求,是几乎直接折半的。于是这个时间复杂度是小于 \(O(n^2\log n )\) 的,接近于 \(O((n+m)\log n)\) 的,其中 \(m\)\(\sum_{i=1}^{n} a_i\)

CODE

#include<bits/stdc++.h>
#define wk(x) write(x),putchar(' ')
#define wh(x) write(x),putchar('\n')
#define ll long long
#define ull unsigned long long
#define ri register int
#define INF 2147483647
#define mod 998244353
#define N 100005
#define NO printf("No\n")
#define YES printf("Yes\n")

using namespace std;
int n,m,k,jk,ans,sum,num,cnt,tot;
int head[N],dis[N],vis[N],wis[N],f[N];

void read(int &x)
{
	x=0;int ff=1;char ty;
	ty=getchar();
	while(!(ty>='0'&&ty<='9'))
	{
		if(ty=='-') ff=-1;
		ty=getchar();
	}
	while(ty>='0'&&ty<='9')
		x=(x<<3)+(x<<1)+ty-'0',ty=getchar();
	x*=ff;return;
}

void write(int x)
{
	if(x==0)
	{
		putchar('0');
		return;
	}
	if(x<0)
	{
		x=-x;
		putchar('-');
	}
	char asd[201];int ip=0;
	while(x) asd[++ip]=x%10+'0',x/=10;
	for(int i=ip;i>=1;i--) putchar(asd[i]);
	return;
}

signed main()
{
	read(jk);while(jk--){
		read(n);ans=0;
		for(int i=1;i<=n;i++) read(dis[i]);//输入。
		for(int i=n-1,bz=0,x=dis[n];i>=1;i--,x=dis[i+1],bz=0){
			for(int j=i;j>=1;j--){
				if(!dis[j]) bz=1;//判断当前位置是否为零。
				dis[j]=x-dis[j];x-=dis[j];//暴力直接求差。
				if(bz){sort(dis+j,dis+i+1);break;}//如果为零,就直接排序退出。
			}if(!bz) sort(dis+1,dis+i+1);//没排过就要排序。
		}wh(dis[1]);//输出。
	}
	return 0;
}
posted @ 2025-11-22 16:16  Red_river_hzh  阅读(3)  评论(0)    收藏  举报