Problem A
问有多少不同面积的三角形,数据量较小,那么我们暴力扫过去丢set就好了。
Problem B
首先我扫完一边后一定是有些位置被站住了,那么根据桶排的思想,每个位置可能存在多个,那么这些多个我们要使它尽可能的多做贡献,就贪心的往后加,最后统计一共有多少位置就可以了。
Problem C
最少要多少次操作可以破环原串的回文性质,那么模拟可以发现,一个回文串只要超出了3,那么他肯定存在字串长度为2或者3的回文串,那么我们只要扫一遍并且在过程中破坏2和3的回文串就可以了。
Problem D
图论题面,其实是思维题,我们统计度数,然后每次在度数还允许的条件下加上点权,可以最优化答案。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
void check_max (int &a,int b) {a=max (a,b);}
void check_min (int &a,int b) {a=min (a,b);}
typedef long long ll;
const int maxn=1e5+10;
ll w[maxn];
ll degree[maxn];
ll v[maxn];
vector <ll> ans;
inline bool cmp (int x,int y) {
return x>y;
}
int main () {
int t; scanf ("%d",&t);
while (t--) {
int n; scanf ("%d",&n);
ll now=0;
ans.clear ();
for (int i=1;i<=n;i++) scanf ("%lld",&w[i]),now+=w[i];
for (int i=1;i<=n-1;i++) {
int x,y; scanf ("%d%d",&x,&y);
degree[x]++;
degree[y]++;
}
int cnt=0;
for (int i=1;i<=n;i++)
for (int j=1;j<degree[i];j++) v[++cnt]=w[i];
sort (v+1,v+cnt+1,cmp);
for (int i=1;i<n;i++) printf ("%lld ",now),now+=v[i];
printf ("\n");
}
return 0;
}