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 个询问,每个询问表 ...
随机推荐
- Appium 服务关键字(转)
来源: https://github.com/appium/appium/blob/master/docs/cn/writing-running-appium/caps.cn.md#appium-服务 ...
- Eclipse_生成webservice客户端
1.工具:eclipse3.3或者是带有webservice插件的eclipse wsdl2java(这个本人没用过,具体长什么样不清楚) 2.步骤: 首先用浏览器访问webservice的站点,点击 ...
- Centos/Fedora下安装Twisted,failed with error code 1 in /tmp/pip-build-H1bj8E/twisted/解决方法
Python踩坑之路 pip/easy_install无法安装Twisted或者安装后无法导入Twisted 看到MM网站上很多图,想用Scrapy框架爬点图,遇到各种库的问题,蛋疼. 一直twist ...
- 浅析Web数据存储-Cookie、UserData、SessionStorage、WebSqlDatabase
Cookie 它是标准的客户端浏览器状态保存方式,可能在浏览器诞生不久就有Cookie了,为什么需要Cookie 这个东东?由于HTTP协议没有状态,所以需要一个标志/存储来记录客户浏览器当前的状态, ...
- Django 2.0 学习(22):Django CSRF
Django CSRF CSRF攻击过程 攻击说明: 1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登陆网站A: 2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时 ...
- jQuery Mobile页面跳转后未加载外部JS原因分析及解决
在使用jQuery Mobile进行Web开发中,当页面跳转时(pageA => pageB),在pageB中引用的JS并未成功运行.因为,JQM并为将整个页面加载到当前的dom中,仅将data ...
- NOIP赛前集训营-提高组(第一场)#B 数数字
题目描述 小N对于数字的大小一直都有两种看法.第一种看法是,使用字典序的大小(也就是我们常用的判断数字大小的方法,假如比较的数字长度不同,则在较短一个前面补齐前导0,再比较字典序),比如43<3 ...
- PowerDesigner在生成SQL时报错Generation aborted due to errors detected during the verification of the mod
一.本章节要用到 ODBC连接数据库直接创建表,请先创建连接库的ODBC 请参考 新建 http://www.cnblogs.com/wdw31210/p/7580286.html 二.生成 去 ...
- MT【127】点对个数两题之一【图论】
在平面上有\(n\) 个点$S={x_1,x_2\cdots,x_n}, $ 其中任意两个点之间的距离至少为 \(1\), 证明在这 \(n\) 个点中距离为 \(1\)的点对数不超过 \(3n\). ...
- python之插入排序
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部 ...