好像已经很久没有写过题解了
C
link
对于每一个糕点,二分查找大于等于它大小的二倍的糕点的位置(可以用\(lower_{}bound\)函数),从这个位置到\(n\)就是可以和这个糕点配对的糕点。
猜猜我是啥
#include<bits/stdc++.h>#define int long longusing namespace std;int n;
int a[500005];
int ans;signed main(){cin >> n;for(int i = 1;i <= n;++ i)cin >> a[i];for(int i = 1;i <= n;++ i){int w = a[i]*2;int wz = lower_bound(a+1,a+1+n,w)-a;ans += n-wz+1;}cout << ans;return 0;}
D
link
设\(d_i\)为\(i\)成年时有的石头数。
首先我们可以得出,石头只会从前往后送;而且我们还可以得出,\(i\)成年后一共会送出\(min(a_i,n-i)\)个石头,也就是会让\(i+1\)到\(i+min(a_i,n-i)\)这些人的石头数加一。
我们知道,区间加一可以用差分,可是差分要全做完才能知道结果,怎么办呢?我们知道如果一个数成年了就不会再得到石头了,也就是说当我们需要知道\(d_i\)时,它就不会再改变了,那么我们就可以边差分边前缀和,做到哪一个需要它了就算到这个的前缀和,后面还是用差分去做区间加一。
点击查看代码
#include<bits/stdc++.h>using namespace std;int n;
int a[500005];
int cf[500005];signed main(){cin >> n;for(int i = 1;i <= n;++ i)cin >> a[i],cf[i] = a[i]-a[i-1];for(int i = 1;i <= n;++ i){a[i] = cf[i-1]+cf[i];cf[i] += cf[i-1];int w = min(a[i],n-i);cf[i+1]++;cf[i+w+1]--;a[i] -= w;}for(int i = 1;i <= n;++ i)cout << a[i] << " ";return 0;}
E
link