A. 简单计算
发现向下整除会损失一些贡献,然后就无法直接用等差数列考虑。
如果不计损失,那么答案是一个等差数列求和。
可以考虑损失的是什么,即$sum limits_{i=1}^{p}i*q mod p$。
这个式子就很好,不妨设$gcd(p,q)=1$,因为$gcd$不为1的情况可以简单的转化为为1的情况。
$i*q 1<=i<=p$在$mod$ $p$意义下会出现$0~p-1$中的每个数一次且仅一次。
所以损失的也是一个等差数列,可以直接计算。
B. 格式化
贪心。
贪心原则:
1.先考虑能够赚内存的,再考虑亏内存的。
2.前者按占用内存大小排序,从小到大,
3.后者按获得内存大小排序,从大到小。
可以看到这个过程实际上是对称的。
证明实际上比较简单。
显然原则1是正确的,在前面多赚一些内存可以尽量减少额外内存的浪费。
在前一个过程中,因为内存不断增加,原则2也是正确的。交换一定不优。
如果考虑原则2的逆过程,似乎就是原则3。但是存在一种更加直观的证明方法。
不妨设当前有内存$k$,有两个内存条$1$,$2$,分别设损失的内存为$cost_1$,$cost_2$,需要占用的内存为$w_1$,$w_2$
如果先格式化$1$更优,而交换会导致不优,有
$k-cost_1>=w_2$
$k-cost_2<w_1$
移项可得$w_2-cost_2<w_1-cost_1$,即排序原则。
所以原则3是正确的。
然后随便写就行了。
C. 真相
为每个人开两个域,分别设为这个人说了真话/假话。
然后可以建出一些边,可以看到这些边在说第一种类型的话的人身上断掉了,所以可以将原序列分成若干个块。
每个块对应着两种选择:
$a$个人说了真话,最后一个人(说的第一种类型的话)也说了真话。
$b$个人说了真话,最后一个人说了假话。
枚举最终有$k$个人说了真话,
那么最后一个人说了真话的块,累计$a$的答案。
最后一个人说了假话的块,累计$b$的答案。
如果最终累计的答案恰好等于$k$,那么即存在一个合法的方案,否则一定不存在。
这个累计答案的过程可以用一个桶简单维护。