1006 Rikka with Graph
hdoj6090题目链接
贪心加边
m<=n-1时,边都从同一个点出发向不同的点连边,呈菊花状
中心点与其余有边的点的距离和:2*m
除中心点外有边的点间的距离和:
m(m−1)2
*2*2(第一个乘2是因为每个点对间的距离为2,第二个乘2是因为每个点对要算两次)
对于没边的点,最少要连的边数为m+1条,最多要连的边数是n-1条,等差数列求和。这部分的距离和为:
(m+1+n−1)[n−1−(m+1)+1]2
*n*2
(乘n是每个点对的距离,乘2是因为每个点对要算两次)
三个部分累加即得第一种情况下的距离和
m>n时,前n-1条边按照按照上面的情况贪心加完成为一朵完好的菊花,先把m=n-1带入第一情况得到一个初始值2*(n-1)+2*(n-1)*(n-2)
剩下的边加在不直接相连的点对之间,每加一条使得两点之间的距离减1,对整体距离和的影响为减2
注意:m有可能大于
n(n−1)2
;答案一定大于等于n*(n-1)
#include<bits/stdc++.h>
using namespace std;
long long n,m;
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%lld%lld",&n,&m);
if(m<=n-1) printf("%lld\n",2*m+2*m*(m-1)+(m+n)*(n-m-1)*n);
else printf("%lld\n",max(2*(n-1)*(n-1)-2*(m-n+1),n*(n-1)));
}
}
1008 Rikka with Subset
hdoj6092题目链接
这题就是母函数的逆过程昂
针对这个题目列出的等式为:
(1+
xa1)(1+xa2)...(1+xan)=b0x0+b1x1+...+bmxm
回顾一下母函数的系数(b数组的操作过程)
之前:
bj−i...bj
之后:
b′j−i...b′j
则
b′j=bj−i+bi
我们存放系数的是同一个数组b,所以需要从后往前操作才能避免覆盖带来的错误
再回到此题,需要采取逆操作,即从前往后操作,详见代码
#include<bits/stdc++.h>
using namespace std;
long long b[10005];
int main()
{
int t,n,m,i,j,k;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=0;i<=m;i++) scanf("%lld",&b[i]);
for(j=i=1;i<=n;i++){
while(!b[j]) j++;
b[j]--;
if(i>1) printf(" ");
printf("%d",j);
if(i==n) { puts("");break; }
for(k=j+1;k<=m;k++) b[k]-=b[k-j];
}
}
}
1011 Rikka with Competition
hdoj6095题目链接
签到快乐
#include<bits/stdc++.h>
using namespace std;
int t,n,k,i,s,a[100005];
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(s=1,i=n-1;i;i--,s++) if(a[i+1]-a[i]>k) break;
printf("%d\n",s);
}
}