对于每个元素,最理想的情况就是都在它的左边或者右边,那么sort一下就可以得到一个特解了,然后大的中间不能有小的元素,因为如果有的话,那么无论选小的还是选大的都不是最优。对小的元素来说,比它大的元素在哪里是没有关系的。所以把大的看作一个整体,然后插空法算出总方案数。
答案用llu存
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef unsigned long long ull; const int mod = 1000000007; const int maxp = 1e5+1000; struct Unit { int v; ull f; bool operator < (const Unit&rhs) const{ return v<rhs.v; } }num[maxp]; ull sum[maxp]; int main() { int T; scanf("%d",&T); int cas = 0; ull ans1,ans2; while(T--){ int p; scanf("%d",&p); for(int i = 0; i < p; i++){ scanf("%d%llu",&num[i].v,&num[i].f); } sort(num,num+p); sum[0] = num[0].f; ans1 = 0; ans2 = 1; for(int i = 1; i < p; i++){ sum[i] = sum[i-1] + num[i].f; } for(int i = 0; i < p;i++){ ans1 = (ans1 + num[i].f*sum[i]); } for(int i = 0,sz = p-1; i < sz; i++){ ans2 = (ans2*(num[i].f+1))%mod; } printf("Case %d: %llu %llu ",++cas,ans1,ans2); } return 0; }