牛客多校8 - Enigmatic Partition(二阶差分)

题目链接:点击查看

题目大意:首先定义 “ n 的拆分 ” 是 n = a[ 1 ] + a[ 2 ] + ... + a[ m ] ,在本题中,n 的拆分需要满足几个条件:

  1. a[ i ] <= a[ i + 1 ] <= a[ i ] + 1 , i ∈ [ 1 , m ]
  2.  1 <= a[ i ] <= n , i ∈ [ 1 , m ]
  3. a[ m ] = a[ 1 ] + 2 

设 f( n ) 为满足上述所有条件下,n 的拆分有多少种,现在给出 t 组查询,每组查询给出一对 [ l , r ] ,求 f( l ) + f( l + 1 ) + ... + f( r )

题目分析:官方题解的做法是枚举 l ,因为每个数一定由连续的 l , l + 1 和 l + 2 组成,暴力去维护 f( n ) ,不过我没看懂,这里就不多展开了

还有一种更加优秀的做法,暂且叫他二阶差分吧,注意是二阶差分,不是二维差分

参考博客:https://www.cnblogs.com/rair/p/13430729.html

牛客多校8 - Enigmatic Partition(二阶差分)_第1张图片

牛客多校8 - Enigmatic Partition(二阶差分)_第2张图片

 牛客多校8 - Enigmatic Partition(二阶差分)_第3张图片

 牛客多校8 - Enigmatic Partition(二阶差分)_第4张图片

牛客多校8 - Enigmatic Partition(二阶差分)_第5张图片 牛客多校8 - Enigmatic Partition(二阶差分)_第6张图片

(最后一个图的num2应该打在13的位置,昨晚上没检查出来,不要被误导(狗头)) 

最后再说一下四个数的特征:

  1. num1:111...123
  2. num2:122...223
  3. num3:num2 + 2
  4. num4: 123...333 + 3

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int N=1e5+100;

LL sum[N*10];

void init()
{
	for(int i=1;i>w;
	int kase=0;
	while(w--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		printf("Case #%d: %lld\n",++kase,sum[r]-sum[l-1]);
	}







    return 0;
}

 

你可能感兴趣的:(差分)