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 个询问,每个询问表 ...
随机推荐
- mysql索引建多了有什么坏处
建立索引常用的规则如下: 1.表的主键.外键必须有索引: 2.数据量超过300的表应该有索引:3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特别是大表 ...
- java 创建过程
- div内元素的居中
1.如果是一行文字(不超过一行) parent{ text-align:center; line-height:div高度; } 2.如果是div内其他类型元素 parent{ height:xxxp ...
- java 连接oracle 进行增删改查
1.在DAO层新增类OraclePersionDao package com.test.dao; import java.sql.*; /** * Created by wdw on 2017/9/1 ...
- FFT常数优化(共轭优化)
最近闲着无聊研究了下\(FFT\)的常数优化,大概就是各种\(3\)次变\(2or1.5\)次之类的,不过没见过啥题卡这个的吧. 关于\(FFT\)可以看这里:浅谈FFT&NTT. 关于复数 ...
- 2017实习【Java研发】面经
标签: 实习 面经 Java研发 阿里.腾讯.华为 找2017暑假实习,经历过被腾讯拒绝的无奈,也有拿到阿里和华为offer的喜悦,找实习过程也有一段时间了,在此把之前的面试知识点和经历做个小总结,以 ...
- Unhandled rejection RangeError: Maximum call stack size exceededill install loadIdealTree
npm安装时候报这个错误,解决方法如下: 删除项目中的 package-lock.json 文件 和 node_modules 文件夹,然后再尝试 npm install 详细参考
- sublime_Text3中snippet设置信息头(包括作者、日期)
1.tool->new snippet(工具->新代码段) 创建一个新的snippet,并保存为author.sublime-snippet(最好在该目录(User)下再创建一个MySni ...
- insert sort
插入排序将数据分为前面有序部分和后面无序部分,取无序部分的第一个元素插入到有序序列中. 注意与选择排序的区别. // insert sortvoid insertionSort(int arr[], ...
- P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚
P4644 [Usaco2005 Dec]Cleaning Shifts 清理牛棚 你有一段区间需要被覆盖(长度 <= 86,399) 现有 \(n \leq 10000\) 段小线段, 每段可 ...