2019年湖南多校第一场||2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
第一场多校就打的这么惨,只能说自己太菜了,还需继续努力啊~
题目链接:
GYM链接:https://codeforces.com/gym/101933
CSU链接:http://acm.csu.edu.cn:20080/csuoj/contest/problemset?cid=2178
A题:
题意:
有n只青蛙掉到了井里,然后可以靠叠罗汉和向上跳逃离水井,每只青蛙有三个属性分别为跳高值,体重(承重能力),身高,问最多能有多少只青蛙能够逃离水井。
思路:
因为每只青蛙的承重能力是有限的,因此我们按照承重能力从大到小排序,然后进行背包,dp[i]表示体重为i最多能达到多高,转移方程为dp[i]=max(dp[i], dp[i+w]+h)。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, d;
int dp[]; struct node {
int l, w, h;
bool operator < (const node& x) const {
return w > x.w;
}
}pp[maxn]; int main() {
scanf("%d%d", &n, &d);
for(int i = ; i <= n; ++i) {
scanf("%d%d%d", &pp[i].l, &pp[i].w, &pp[i].h);
}
sort(pp + , pp + n + );
int ans = ;
for(int i = ; i <= n; ++i) {
int w = pp[i].w;
for(int j = ; j < w && (j + w) <= 1e8; ++j) {
dp[j] = min(d + , max(dp[j], dp[j+w] + pp[i].h));
}
if(dp[w] + pp[i].l > d) ++ans;
}
printf("%d\n", ans);
return ;
}
B题:
题意:
给你n个数字或者字符串,问你是否能够把它还原成1~n。
思路:
直接On遍历即可。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n;
char s[]; int main() {
int flag = ;
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%s", s);
if(s[] == 'm') continue;
int len = strlen(s);
int num = ;
for(int j = ; j < len; j++) {
num = num * + s[j] - '';
}
if(num != i) flag = ;
}
if(flag) puts("makes sense");
else puts("something is fishy");
return ;
}
C题:
题意:
给定n天产生垃圾,第i天垃圾的累积量为,如果累积量在j+1天会大于等于20,则需在前一天打扫卫生,问至少需要打扫多少次卫生。
思路:
枚举天数,然后与前面没被清理的垃圾进行累计求和,如果大于等于20则将前面的垃圾清空。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n;
int a[maxn], vis[maxn]; int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
int ans = ;
for(int i = ; i <= ; i++) {
int sum = ;
for(int j = ; j <= n; j++) {
if(a[j] > i) break;
if(vis[a[j]]) continue;
sum += i - a[j];
if(sum >= ) {
ans++;
sum = ;
for(int k = ; k < i; k++) vis[k] = ;
break;
}
}
}
printf("%d\n", ans);
return ;
}
D题:
题意:
有一家披萨店要配送披萨,给定一张有n个结点的图和m条有边权的边,有q份订单,每份订单给定下单时间,终点,制作这份披萨结束的时间,问你这q份订单中要等待的最长时间的最小值(注意一次可以配送多份订单,但需要按照下单时间来,下单时间和制作完成时间单调递增)。
思路:
因为一次可以拿多份披萨进行配送且必须按照顺序配送,因此我们先跑n遍dijstra求出任意两点间的最短路。
二分需要等待的最长时间的最小值x,然后check进行dp,dp[u]表示配送完u这份订单且回到起点(1)的最短时间,由于q不大,因此我们可以枚举分界点进行分段,总复杂度为O(nmlog(n)+35q2)。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e3 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m, q, tot, u, v, w;
int head[maxn], vis[maxn];
LL dis[maxn][maxn], dp[maxn]; struct edge {
int v, w, next;
}ed[maxn*]; struct node {
int s, t, u;
}num[maxn]; void add(int u, int v, int w) {
ed[tot].v = v;
ed[tot].w = w;
ed[tot].next = head[u];
head[u] = tot++;
} void dij(int s) {
priority_queue<pLi, vector<pLi>, greater<pLi> > q;
for(int i = ; i <= n; ++i) {
vis[i] = ;
dis[s][i] = INF;
}
dis[s][s] = ;
q.push({, s});
int u, v;
while(!q.empty()) {
u = q.top().second; q.pop();
if(vis[u]) continue;
vis[u] = ;
for(int i = head[u]; ~i; i = ed[i].next) {
v = ed[i].v;
if(dis[s][v] > dis[s][u] + ed[i].w) {
dis[s][v] = dis[s][u] + ed[i].w;
q.push({dis[s][v], v});
}
}
}
} bool check(LL x) {
for(int i = ; i <= q; ++i) dp[i] = INF;
for(int i = ; i < q; ++i) {
LL tmp = , las = dp[i], pp = INF;
for(int j = ; i + j <= q; ++j) {
int v = i + j;
if(j == ) tmp += dis[][num[v].u];
else tmp += dis[num[v-].u][num[v].u];
las = max(dp[i], 1LL * num[v].t);
if(las + tmp - num[v].s > x) break;
pp = min(pp, x + num[v].s - tmp);
if(pp < las) break;
dp[v] = min(dp[v], las + tmp + dis[num[v].u][]);
}
}
return dp[q] < INF;
} int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) {
head[i] = -;
}
for(int i = ; i <= m; ++i) {
scanf("%d%d%d", &u, &v, &w);
add(u, v, w), add(v, u, w);
}
for(int i = ; i <= n; ++i) dij(i);
scanf("%d", &q);
for(int i = ; i <= q; ++i) {
scanf("%d%d%d", &num[i].s, &num[i].u, &num[i].t);
}
LL ub = 1e15, lb = , mid, ans = ;
while(ub >= lb) {
mid = (ub + lb) >> ;
if(check(mid)) {
ub = mid - ;
ans = mid;
} else {
lb = mid + ;
}
}
printf("%lld\n", ans);
return ;
}
E题:
题意:
己方有n个小兵,敌方有m个小兵,每个小兵的血量给定,现在总共有d点伤害,d点伤害会一点一点地对场上所有活着的小兵中的某一个造成一点伤害(包括己方),每个小兵收到这点伤害的概率相等,问敌方小兵全死的概率。
思路:
有两种方法,一种是用十进制记录每个小兵现在还剩多少的血量,另一种是记录剩余血量为i的小兵有多少个,然后进行记忆化搜索,貌似第二种方法快一点。
代码实现如下:
第一种方法:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m, d, cnt, sum;
int a[], b[], c[];
LL pw[];
LL las;
unordered_map<LL, double> dp; void update(LL& x) {
cnt = ;
for(int i = n; i > ; --i) a[i] = x % , x /= ;
for(int i = m; i > ; --i) b[i] = x % , x /= ;
sort(a + , a + n + );
sort(b + , b + m + );
for(int i = ; i <= m; ++i) x = x * + b[i];
for(int i = ; i <= n; ++i) x = x * + a[i];
for(int i = ; i <= n; ++i) {
c[n+-i] = a[i];
if(a[i] > ) cnt++;
}
for(int i = ; i <= m; ++i) {
c[n+m+-i] = b[i];
if(b[i] > ) cnt++;
}
} double dfs(LL nw, int d) {
update(nw);
int p[];
int num = cnt;
if(dp.find(nw) != dp.end()) return dp[nw];
if(nw < las) return dp[nw] = 1.000000;
if(d == ) return dp[nw] = 0.000000;
double tmp = ;
for(int i = ; i <= n + m; ++i) p[i] = c[i];
for(int i = ; i <= n + m; ++i) {
if(p[i] == ) continue;
--p[i];
if(p[i] == ) num--;
tmp += dfs(nw - pw[i], d - ) / (num + (p[i] == ));
if(p[i] == ) num++;
++p[i];
}
return dp[nw] = tmp;
} int main() {
scanf("%d%d%d", &n, &m, &d);
for(int i = ; i <= n; ++i) scanf("%d", &a[i]), sum += a[i];
for(int i = ; i <= m; ++i) scanf("%d", &b[i]), sum += b[i];
if(d >= sum) return printf("1.000000\n") * ;
LL nw = ;
las = ;
cnt = n + m;
for(int i = ; i <= m; ++i) nw = nw * + b[i], c[n+m+-i] = b[i];
for(int i = ; i <= n; ++i) nw = nw * + a[i], las = las * , c[n+-i] = a[i];
pw[] = ;
for(int i = ; i <= n + m; ++i) pw[i] = pw[i-] * ;
printf("%.7f\n", dfs(nw, d));
return ;
}
第二种方法:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m, d;
LL pw[];
unordered_map<LL, double> dp;
int a[], b[]; double dfs(LL nw, int d) {
if(dp.find(nw) != dp.end()) return dp[nw];
if(nw < pw[]) return dp[nw] = 1.0;
if(d == ) return dp[nw] = 0.0;
double tmp = ;
int num = ;
LL pp = nw;
for(int j = ; j <= ; ++j) {
num += pp % ;
pp /= ;
}
for(int i = ; i <= ; ++i) {
int x = (nw % pw[i+]) / pw[i];
if(x == ) continue;
nw -= pw[i];
if(i != && i != ) nw += pw[i-];
tmp += x * dfs(nw, d - ) / num;
nw += pw[i];
if(i != && i != ) nw -= pw[i-];
}
return dp[nw] = tmp;
} int main() {
scanf("%d%d%d", &n, &m, &d);
int sum = ;
for(int i = ; i <= n; ++i) scanf("%d", &a[i]), sum += a[i];
for(int i = ; i <= m; ++i) scanf("%d", &b[i]), sum += b[i];
if(sum <= d) return printf("1.0000000\n") * ;
LL nw = ;
pw[] = ;
for(int i = ; i <= ; ++i) pw[i] = pw[i-] * ;
for(int i = m; i >= ; --i) nw += pw[+b[i]];
for(int i = n; i >= ; --i) nw += pw[a[i]];
printf("%.7f\n", dfs(nw, d));
return ;
}
H题:
题意:
你有一块边长为l的花园,然后有n个修理机器可以考虑,每个修理机器有名字、花费、工作速度、工作时间、充电时间,要你输出开销最小且能保证每周至少修理一次的所有机器的名字。
思路:
我们先按照花费从小到大排序然后计算是否能够保证每周至少修理一次即可。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int l, m;
char s[]; struct node {
char name[];
int p, c, t, r, id;
bool operator < (const node& x) const {
return p == x.p ? id < x.id : p < x.p;
}
}num[]; int main() {
char* p;
scanf("%d%d", &l, &m);
getchar();
for(int i = ; i <= m; ++i) {
memset(s, '\0', sizeof(s));
fgets(s, , stdin);
num[i].id = i;
p = strtok(s, ",");
int j = ;
while(p) {
if(j == ) strcpy(num[i].name, p);
else if(j == ) num[i].p = atoi(p);
else if(j == ) num[i].c = atoi(p);
else if(j == ) num[i].t = atoi(p);
else num[i].r = atoi(p);
j++;
p = strtok(NULL, ",");
}
}
sort(num + , num + m + );
int mx = inf;
for(int i = ; i <= m; ++i) {
if(10080.0 / (num[i].t + num[i].r) * num[i].c * num[i].t >= 1.0 * l) {
if(mx == inf || mx == num[i].p) {
printf("%s\n", num[i].name);
mx = num[i].p;
}
}
}
if(mx == inf) puts("no such mower");
return ;
}
I题:
题意:
题目我没读,不过大意差不多就是要你用这n个参赛人的权值凑出S,问恰好凑成S需要多少个人并输出他们的名字,权值按照从小到大排序保证前一个会小于等于当前数的一半。
思路:
因为题目保证第i小的数一定小于等于第i+1小的数的一半,因此我们可以得知将所有数按照从大到小排序然后能取的都取,最后看S是否会减为0,本题唯一难点就是需要大数,因此去学了一波java容器。
代码实现如下:
import java.math.*;
import java.util.*; public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n;
BigInteger sum;
n = sc.nextInt();
sum = sc.nextBigInteger();
Map<BigInteger, String> mp = new HashMap<BigInteger, String>();
Vector<BigInteger> v = new Vector<BigInteger>();
String s;
BigInteger num;
for(int i = 1; i <= n; i++) {
s = sc.next();
num = sc.nextBigInteger();
mp.put(num, s);
v.add(num);
}
Collections.sort(v, Collections.reverseOrder());
Vector<String> ans = new Vector<String>();
for(int i = 0; i < n; i++) {
if(sum.compareTo(v.elementAt(i)) >= 0) {
ans.add(mp.get(v.elementAt(i)));
sum = sum.subtract(v.elementAt(i));
}
}
if(sum.compareTo(BigInteger.valueOf(0)) != 0) {
ans.removeAllElements();
}
System.out.println(ans.size());
for(int i = 0; i < ans.size(); i++) {
System.out.println(ans.elementAt(i));
}
sc.close();
}
}
J题:
题意:
需要你构造一个01串,该01串需满足从其中任选两个字符保持原来的相对顺序,恰好有a种方法得到00,b种方法得到01,c种方法得到10,d种方法得到11。
思路:
因为是任选两个,因此我们可以通过组合数解出0的个数n和1的个数m(注意当a等于1时n等于2,d等于1时同理),当n*m!=b+c或者无法解除n或m时是无法构造的。
构造时我们发现讲1全部放左边0全部放右边,然后对于某一个0,每前移通过一个1都会多一个01,少一个10,通过比较b-num(num为当前已有01个数)与m比较知道这个0该放在哪里。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = 1e6 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; LL a, b, c, d, n, m;
vector<int> v; int main() {
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
if(a == && b == && c == && d == ) return printf("1\n") * ;
if(a >= ) {
n = (LL)sqrt( * a) + ;
if(n * (n - ) != * a) return printf("impossible\n") * ;
} else if(a == ) n = ;
else {
if(b != || c != ) n = ;
}
if(d >= ) {
m = (LL)sqrt( * d) + ;
if(m * (m - ) != * d) return printf("impossible\n") * ;
} else if(d == ) m = ;
else {
if(b != || c != ) m = ;
}
if(n * m != b + c) return printf("impossible\n") * ;
int num = ;
while(num < b) {
if(b - num >= m) {
v.push_back();
n--;
num += m;
} else {
int cnt = ;
for(int i = ; i < m - (b - num); i++) {
v.push_back();
cnt++;
}
num = b;
m -= cnt;
v.push_back();
n--;
break;
}
}
while(m--) v.push_back();
while(n--) v.push_back();
for(auto x : v) {
printf("%d", x);
}
printf("\n");
return ;
}
K题:
题意:
给你n和k,表示有一棵有n个结点的树要你使用恰好k个颜色进行染色,求满足相邻结点颜色不相同的方案数。
思路:
我们定义f(x)为至多使用了x种颜色的方案数,易知当我们确定父亲结点的颜色后子结点的颜色只需要和父亲节点的颜色不同即可,因此除0号结点染色方案数为x外其他的都是x-1种方法,最后容斥一下即可。
代码实现如下:
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> piL;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-;
const int mod = 1e9 + ;
const int maxn = + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, k;
LL A[maxn]; LL qpow(LL x, int n) {
LL res = ;
while(n) {
if(n & ) res = res * x % mod;
x = x * x % mod;
n >>= ;
}
return res;
} LL get_num(int k) {
return 1LL * k * qpow(k - , n - ) % mod;
} LL C(int n, int m) {
return A[n] * qpow(A[m], mod - ) % mod * qpow(A[n-m], mod - ) % mod;
} int main() {
scanf("%d%d", &n, &k);
A[] = ;
for(int i = ; i <= k; i++) {
A[i] = A[i-] * i % mod;
}
for(int i = ; i < n; i++) {
scanf("%*d");
}
int flag = ;
LL ans = ;
for(int i = k; i >= ; i--) {
LL tmp = get_num(i) * C(k, i) % mod;
if(flag == ) ans = (ans + tmp) % mod;
else ans = (ans - tmp + mod) % mod;
flag = -flag;
}
printf("%lld\n", ans);
return ;
}
2019年湖南多校第一场||2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)的更多相关文章
- (寒假GYM开黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) author: &qu ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举
2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)- D. Delivery Delays -二分+最短路+枚举 ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp
2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)-E. Explosion Exploit-概率+状压dp [P ...
- Gym .101933 Nordic Collegiate Programming Contest (NCPC 2018) (寒假gym自训第四场)
(本套题算是比较温和吧,就是罚时有点高. B .Baby Bites 题意:给出一个婴儿给出的数组,有一些数字听不清楚,让你还原,问它是否是一个从1开始的一次增加的数组. 思路:从左往右依次固定,看是 ...
- 模拟赛小结:2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
比赛链接:传送门 两个半小时的时候横扫了铜.银区的所有题,签到成功混进金区.奈何后面没能开出新的题. 最后一个小时的时候xk灵机一动想出了D题的做法,讨论了一波感觉可行,赶紧去敲.结束前2分钟终于过了 ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) - 4.28
赛后补了几道 赛中我就写了两个... A - Altruistic AmphibiansGym - 101933A 看了眼榜没几个人做.就没看. 最后发现就是一个DP(但是我觉得复杂度有点迷) 题意: ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) Solution
A. Altruistic Amphibians Upsolved. 题意: $有n只青蛙,其属性用三元组表示 <l_i, w_i, h_i> l_i是它能跳的高度,w_i是它的体重,h_ ...
- [十一集训] Day1 (2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018))
A Altruistic Amphibians 原题 题目大意: n只青蛙在高度为d的井中,每只有跳跃距离.重量和高度,每只青蛙可以借助跳到别的青蛙的背上而跳出井,每只青蛙能承受的最大重量是自身重量, ...
- 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) D. Delivery Delays (二分+最短路+DP)
题目链接:https://codeforc.es/gym/101933/problem/D 题意:地图上有 n 个位置和 m 条边,每条边连接 u.v 且有一个距离 w,一共有 k 个询问,每个询问表 ...
随机推荐
- gitlab修改root密码
在root用户下,执行 [root@localhost gitlab]# sudo gitlab-rails console production -------------------------- ...
- Js获取上一月份
new Date(new Date().setMonth(new Date().getMonth() - 1))
- SpringBoot(五)_表单验证
SpringBoot(五)_表单验证 参数校验在我们日常开发中非常常见,最基本的校验有判断属性是否为空.长度是否符合要求等,在传统的开发模式中需要写一堆的 if else 来处理这些逻辑,很繁琐,效率 ...
- Kafka高可用实现
数据存储格式 Kafka的高可靠性的保障来源于其健壮的副本(replication)策略.一个Topic可以分成多个Partition,而一个Partition物理上由多个Segment组成. Seg ...
- Class.getResourceAsStream 和 ClassLoder.getResourceAsStream 的区别
问题描述 最近学习MyBaits时用到了 InputStream Resources.getResourceAsStream(String resource)来读取MyBatis配置文件,为了方便使用 ...
- springboot学习笔记-3 整合redis&mongodb
一.整合redis 1.1 建立实体类 @Entity @Table(name="user") public class User implements Serializable ...
- UFLDL学习笔记 ---- 主成分分析与白化
主成分分析(PCA)是用来提升无监督特征学习速度的数据降维算法.看过下文大致可以知道,PCA本质是对角化协方差矩阵,目的是让维度之间的相关性最小(降噪),保留下来的维度能量最大(去冗余),PCA在图像 ...
- python对excel操作
学习一下:原文链接:http://www.cnblogs.com/lhj588/archive/2012/01/06/2314181.html 一.安装xlrd模块 到python官网下载http:/ ...
- 【刷题】洛谷 P3455 [POI2007]ZAP-Queries
题目描述 Byteasar the Cryptographer works on breaking the code of BSA (Byteotian Security Agency). He ha ...
- 洛谷P4233 射命丸文的笔记 【多项式求逆】
题目链接 洛谷P4233 题解 我们只需求出总的哈密顿回路个数和总的强联通竞赛图个数 对于每条哈密顿回路,我们统计其贡献 一条哈密顿回路就是一个圆排列,有\(\frac{n!}{n}\)种,剩余边随便 ...