Description:
Input:
Output:
Sample Input:
Sample Input 0
3
1 3 6
Sample Input 1
5
4 2 9 10 1
Sample Output:
Sample Output 0
73
Sample Output 1
971
Data Constraint:
1<=n<=10^6
1<=ai<=10^9
题目大意:
给一个长度为n的序列,可以把它分成若干段,每次的价值为
∑ni=1a[i]∗i所在区间的长度
求所有分法的贡献和。
吹水:
这道题其实不难,但是考场花了近2小时才弄出来,如果正式比赛这样就完了。
首先我想到的是确定每个点被覆盖了多少次,大概需要对覆盖区间的长度分类讨论,但是我没有去算样例,于是打了近一个多小时发现不对,我没有考虑除了这个区间的区间组合方案,再仔细思考得出我这个思路竟然是不行的(赛后讨论中有人说用这个思路做出来了%%%)。
于是想到了dp……
题解:
这个是分区间的问题,根据经验,我们很容易想到去dp。
设
fi
表示在i这里必须断开,1-i的所有方案的价值和。
gi
表示1-i分的方案数。
朴素dp:
gi=∑i−1j=0gj
fi=∑i−1j=0f[j]+g[j]∗sumj+1..i∗(i−j)
我在打了表后才想到
gi=2i−1
。
其实
fi
的dp是明显可以改进的。
fi−1
和
fi
的dp有很多相同的地方,让我来写一下。
fi+1=∑ij=0f[j]+g[j]∗sumj+1..i+1∗(i−j+1)
fi+1=∑i−1j=0g[j]∗sumj+1..i+1∗(i−j+1)+∑ij=0fj+gi∗ai+1
fi+1=∑i−1j=0g[j]∗(sumj+1..i∗(i−j)+sumj+1..i+ai+1∗(i−j+1))+∑ij=0fj+gi∗ai+1
fi+1=2∗fi+gi∗ai+1+∑i−1j=0gj∗(sumj+1..i+ai+1∗(i−j+1))
然后我们就发现后面只要维护一些东西的和就可以O(1)算了。
其实我比赛时写的式子不是这个,这个是乱推的。