hihoCoder编程练习赛67

题目1 : 序列

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

给定两个正整数 n, P,求知足如下两个条件的长度为 n 的序列 ai 个数:ios

1. 1 ≤ ai ≤ Pide

2. 不存在 1 ≤ l ≤ r ≤ n,知足al + al+1 + ... + ar 是 P 的倍数ui

因为方案数可能很大,你只须要输出方案数对 109+7 取模的值spa

输入

第一行两个正整数 n,Pcode

1 ≤ n, P ≤ 104blog

输出

输出方案数对  109+7 取模的值ip

样例解释

知足条件的序列有两个:{1,1} 和 {2,2}内存

样例输入ci

2 3

样例输出input

2

 1 #include <iostream>
 2 #define ll long long
 3 
 4 using namespace std;  5 
 6 const ll MOD = 1000000007;  7 
 8 int main()  9 { 10  ll n, p; 11     while(cin>>n>>p){ 12         ll ans = 1; 13         p--; 14         while(n--){ 15             ans *= p; 16             ans %= MOD; 17             p--; 18  } 19         cout<<ans<<endl; 20  } 21 
22     return 0; 23 }
View Code

 

题目2 : 彩球

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

有一家商店,一共有 n × k 个彩球。球一共有 n 种颜色,每种颜色的球都是有刚好 k 个,如今你要从这 n×k 个球中选 n 个球,要求他们的颜色互不相同,求有几种选择的方案,因为方案数可能很大,你只须要输出方案数对 P 取模后的值。

输入

第一行三个正整数 n, k, P

对于50%的数据,有1 ≤ n, k, P ≤ 109

对于100%的数据,有1 ≤ n, k, P ≤ 1018

输出

输出方案数对 P 取模后的值

样例输入
2 2 100000
样例输出
4
 1 def quick_pow(a, n, mod):  2     ans = 1
 3     while(n!=0):  4         if(n%2==1):  5             ans = ans*a%mod  6         a = a*a%mod  7         n = n // 2
 8     return ans  9 
10 if __name__ == '__main__': 11     n, k, mod = raw_input().strip().split() 12     n = long(n) 13     k = long(k) 14     mod = long(mod) 15     print quick_pow(k, n, mod)
View Code

 

题目3 : 最优子段

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

给定一个长度为 n 的序列 ai 和两个整数 A, B,要求你找一对数l, r,要求1 ≤ l ≤ r 且A×(ai+ai+1+...+ar)+B 最大

输入

第一行三个整数 n, A, B

第二行 n 个整数,第 i 个整数表示 ai

1 ≤ n ≤ 106

-106 ≤ A, B, ai ≤ 106

输出

输出最大的A×(ai+ai+1+...+ar)+B

样例解释

选择 (1,1) 或者 (4,4) 均可以

样例输入
4 2 3
0 -2 -2 0
样例输出
3
 1 #include <iostream>
 2 #define ll long long
 3 
 4 using namespace std;  5 
 6 const int N = 1000010;  7 
 8 ll arr[N];  9 
10 ll dp(ll n){ 11     ll ans = 0; 12     ll sum = 0; 13     for(int i = 0; i <n; i++){ 14         sum += arr[i]; 15         ans = max(ans, sum); 16         if(sum < 0)sum = 0; 17  } 18     return ans; 19 } 20 
21 int main() 22 { 23  ll n, A, B; 24     while(cin>>n>>A>>B){ 25         for(int i = 0; i < n; i++){ 26             cin>>arr[i]; 27             if(A<0)arr[i] *= -1; 28  } 29         if(A<0)cout<<-A*dp(n)+B<<endl; 30         else cout<<A*dp(n)+B<<endl; 31  } 32 
33     return 0; 34 }
View Code

 

题目4 : 公路收费

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

A 国有 n 个城市,第 i 个城市有 ai 个会议表明,这 n 个城市经过 n-$ 条双向的高速公路链接,保证每两个城市均可以经过高速公路互相到达,每一个人经过一条高速公路都要付相应的费用。

如今 A 国的总统想挑选一个城市做为会议中心,要求全国全部会议表明都到这个城市来,为了方便你们出行,A 国的总统可让不超过 k 条高速公路的收费变为 0 。

如今你要安排挑选的城市和免费的高速公路,最小化的全部会议表明的路费总和。

输入

第一行两个整数 n, k

第二行 n 个非负整数,第 i 个表示ai

接下来 n-1 行,每行三个整数 u, v, w,描述一条收费为 w 的高速公路 (u, v)

1 ≤ n ≤ 103

0 ≤ k ≤ n-1

1 ≤ w, ai≤ 105

输出

输出最小的路费总和

样例解释

让 (2,3) 免费,而后选 2 做为会议城市

样例输入
3 1
1 2 3
1 2 1
2 3 2
样例输出
1
 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 #define ll long long
 7 
 8 using namespace std;  9 
10 const int N = 1010; 11 const ll INF = 0x3f3f3f3f3f3f3f3f; 12 
13 ll arr[N], sum[N]; 14 
15 struct Edge{ 16     int to, w, next; 17 }edges[2*N]; 18 int head[N], tot; 19 
20 void init(){ 21     memset(head, -1, sizeof(head)); 22     tot = 0; 23 } 24 
25 void add_edge(int u, int v, int w){ 26     edges[tot].to = v; 27     edges[tot].w = w; 28     edges[tot].next = head[u]; 29     head[u] = tot++; 30 } 31 
32 vector<ll> vec; 33 int n, k; 34 
35 void dfs(int u, int fa){ 36     sum[u] = arr[u]; 37     for(int i = head[u]; i != -1; i = edges[i].next){ 38         int v = edges[i].to; 39         int w = edges[i].w; 40         if(v != fa){ 41  dfs(v, u); 42             sum[u] += sum[v]; 43             vec.push_back(sum[v]*w); 44  } 45  } 46 } 47 
48 ll work(int s){ 49  vec.clear(); 50 
51     dfs(s, 0); 52  sort(vec.begin(), vec.end()); 53     ll ans = 0; 54     for(int i = 0; i < n-k-1; i++) 55         ans += vec[i]; 56     return ans; 57 } 58 
59 int main() 60 { 61     while(cin>>n>>k){ 62         for(int i = 1; i <= n; i++) 63             cin>>arr[i]; 64         int u, v, w; 65  init(); 66         for(int i = 0; i < n-1; i++){ 67             cin>>u>>v>>w; 68  add_edge(u, v, w); 69  add_edge(v, u, w); 70  } 71         ll ans = INF; 72         for(int i = 1; i <= n; i++){ 73             ans = min(ans, work(i)); 74  } 75         cout<<ans<<endl; 76  } 77     return 0; 78 }
View Code
相关文章
相关标签/搜索