第九届福建省大学生程序设计竞赛 2018.8.26组队训练赛

题目链接:http://acm.fzu.edu.cn/contest/list.php?cid=158

A题题目:

题意:

  给你六种操作:def, mul,mod,div, add, sub。除了看这几个字母也都知道是啥意思了,其中def是进行define。

思路:

  比赛时队友写的,直接模拟,不过赛后补题时队友和我说mul时需要快速乘。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long LL;
17 typedef pair<LL, LL> pLL;
18 typedef pair<LL, int> pli;
19 typedef pair<int, LL> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long uLL;
22
23 #define lson i<<1
24 #define rson i<<1|1
25 #define lowbit(x) x&(-x)
26 #define bug printf("*********\n");
27 #define debug(x) cout<<"["<<x<<"]" <<endl;
28 #define FIN freopen("D://code//in.txt", "r", stdin);
29 #define IO ios::sync_with_stdio(false),cin.tie(0);
30
31 const double eps = 1e-8;
32 const LL mod = 1LL<<47;
33 const int maxn = 1e6 + 7;
34 const double pi = acos(-1);
35 const int inf = 0x3f3f3f3f;
36
37 LL x;
38 string op, s, t;
39 map<string, LL> mp;
40
41 LL mul(LL a, LL b) {
42     LL ans = 0;
43     while(b) {
44         if(b & 1) ans = (ans + a) % mod;
45         a = a * 2 % mod;
46         b >>= 1;
47     }
48     return ans % mod;
49 }
50
51 int main() {
52     //FIN;
53     IO;
54     while(cin >>op) {
55         if(op == "def") {
56             cin >>s >>x;
57             mp[s] = x % mod;
58             cout <<s <<" = " <<mp[s] <<endl;
59         } else if(op == "sub") {
60             cin >>s >>t;
61             mp[s] = (mp[s] - mp[t] + mod) % mod;
62             cout <<s <<" = " <<mp[s] <<endl;
63         } else if(op == "add") {
64             cin >>s >>t;
65             mp[s] = (mp[s] + mp[t]) % mod;
66             cout <<s <<" = " <<mp[s] <<endl;
67         } else if(op == "div") {
68             cin >>s >>t;
69             mp[s] = (mp[s] / mp[t] + mod) % mod;
70             cout <<s <<" = " <<mp[s] <<endl;
71         } else if(op == "mul") {
72             cin >>s >>t;
73             mp[s] = mul(mp[s], mp[t]) % mod;
74             cout <<s <<" = " <<mp[s] <<endl;
75         } else {
76             cin >>s >>t;
77             mp[s] = mp[s] % mp[t];
78             cout <<s <<" = " <<mp[s] <<endl;
79         }
80     }
81     return 0;
82 }

B题最大权闭合子图,待补。

D题题目:

题意:

  对于一个x,初始值为1,进行q次操作,模数是m。操作种类有两种:乘以x,处以第x次操作的那个数,每次操作输出x。

思路:

  比赛时队友耿直的进行模拟,自信WA了。然后帮他debug没搞出来就换我来写,我一上来就来了JAVA大数和C++大数,都T了。正在无解时,突然发现每个除的数只会被除一次,然后想到一个骚操作,没想到是正解~对于乘法很容易,对于除法:我们除了那个数就相当于前面没有乘以那个数,那么我们该如何记录没有进行第x次操作其他操作全都进行了呢?我和队友说这个思路时,突然想到线段树,我们以操作的步数为区间,如第一次操作就是大区间的左端点,q为右端点。每次乘就是将当前对应的那个点的值update为x,除就是将第x次操作对应的那个值update为1,输出的结果则是从1到当前操作的值的乘积。具体情况看代码~

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long LL;
17 typedef pair<LL, LL> pLL;
18 typedef pair<LL, int> pli;
19 typedef pair<int, LL> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long uLL;
22
23 #define lson rt<<1
24 #define rson rt<<1|1
25 #define IO ios::sync_with_stdio(false),cin.tie(0);
26
27 const double eps = 1e-8;
28 const int mod = 1e9 + 7;
29 const int maxn = 1e5 + 7;
30 const double pi = acos(-1);
31
32 int t, q, m, x;
33 char s[5];
34
35 struct node {
36     int l, r;
37     LL mul;
38 }segtree[maxn<<2];
39
40 void push_up(int rt) {
41     segtree[rt].mul = ((segtree[lson].mul % m) * (segtree[rson].mul % m)) % m;
42 }
43
44 void build(int rt, int l, int r) {
45     segtree[rt].l = l, segtree[rt].r = r;
46     segtree[rt].mul = 1;
47     if(l == r) return;
48     int mid = (l + r) >> 1;
49     build(lson, l, mid);
50     build(rson, mid + 1, r);
51     push_up(rt);
52 }
53
54 void update(int rt, int pos, int val) {
55     if(segtree[rt].l == pos && segtree[rt].r == pos) {
56         segtree[rt].mul = val;
57         return;
58     }
59     int mid = (segtree[rt].l + segtree[rt].r) >> 1;
60     if(pos <= mid) update(lson, pos, val);
61     else update(rson, pos, val);
62     push_up(rt);
63 }
64
65 int main() {
66     scanf("%d", &t);
67     while(t--) {
68         scanf("%d%d", &q, &m);
69         build(1, 1, q);
70         for(int i = 1; i <= q; i++) {
71             scanf("%s%d", s, &x);
72             if(s[0] == ‘M‘) {
73                 update(1, i, x);
74             } else {
75                 update(1, x, 1);
76             }
77             printf("%lld\n", segtree[1].mul);
78         }
79     }
80     return 0;
81 }

E题题目:

题意:

  一个n个节点m条边的无向图,要求出s到t的最短时间。每条边有权值(通过时间),对于每个节点有一个限制,即你每次只能在[2*K*ai,(2*K+1)ai)(K为任意实数)内从该节点离开。

思路:

  裸的最短路,判断一下每次到达u这个节点时时a[u]的奇数倍还是偶数倍即可。

代码实现如下:

  1 #include <set>
  2 #include <map>
  3 #include <queue>
  4 #include <stack>
  5 #include <cmath>
  6 #include <bitset>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15
 16 typedef long long LL;
 17 typedef pair<LL, LL> pLL;
 18 typedef pair<LL, int> pli;
 19 typedef pair<int, LL> pil;;
 20 typedef pair<int, int> pii;
 21 typedef unsigned long long uLL;
 22
 23 #define lson i<<1
 24 #define rson i<<1|1
 25 #define lowbit(x) x&(-x)
 26 #define IO ios::sync_with_stdio(false),cin.tie(0);
 27
 28 const double eps = 1e-8;
 29 const int maxn = 1e6 + 7;
 30 const double pi = acos(-1);
 31 const int inf = 0x3f3f3f3f;
 32
 33 int t, n, m, tot, u, v, w, s, e;
 34 int head[1007], vis[1007];
 35 LL a[1007];
 36 LL dis[1007];
 37
 38 struct node {
 39     int v, next;
 40     LL w;
 41 }ed[1007*1007 / 2];
 42
 43 void addedge(int u, int v, LL w) {
 44     ed[tot].v = v;
 45     ed[tot].w = w;
 46     ed[tot].next = head[u];
 47     head[u] = tot++;
 48     ed[tot].v = u;
 49     ed[tot].w = w;
 50     ed[tot].next = head[v];
 51     head[v] = tot++;
 52 }
 53
 54 void dij(int s) {
 55     priority_queue<pli,vector<pli>,greater<pli> >q;
 56     for(int i = 1; i <= n; i++) dis[i] = 1000000000;
 57     dis[s] = 0;
 58     q.push(make_pair(0, s));
 59     while(!q.empty()) {
 60         int u = q.top().second;
 61         q.pop();
 62         if(vis[u]) continue;
 63         vis[u] = 1;
 64         for(int i = head[u]; ~i; i = ed[i].next) {
 65             int v = ed[i].v;
 66             LL len = dis[u] + ed[i].w;
 67             if(a[v] && v != e) {
 68                 int k = len / a[v];
 69                 if(k & 1) len = (k + 1) * a[v];
 70             }
 71             if(len < dis[v]) {
 72                 dis[v] = len;
 73                 q.push(make_pair(dis[v], v));
 74             }
 75         }
 76     }
 77 }
 78
 79 int main() {
 80     //FIN;
 81     IO;
 82     cin >>t;
 83     while(t--) {
 84         cin >>n >>m;
 85         tot = 0;
 86         memset(vis, 0, sizeof(vis));
 87         memset(head, -1, sizeof(head));
 88         for(int i = 1; i <= n; i++) {
 89             cin >>a[i];
 90         }
 91         for(int i = 1; i <= m; i++) {
 92             cin >>u >>v >>w;
 93             addedge(u, v, w);
 94         }
 95         cin >>s >>e;
 96         dij(s);
 97         cout <<dis[e] <<endl;
 98     }
 99     return 0;
100 }

G题题目:

题意:

  求两个矩形面积交/面积并。

思路:

  比赛时队友用扫描线过的,其实对于只有两个矩形,贪心即可。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long LL;
17 typedef pair<LL, LL> pLL;
18 typedef pair<LL, int> pli;
19 typedef pair<int, LL> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long uLL;
22
23 #define lson i<<1
24 #define rson i<<1|1
25 #define lowbit(x) x&(-x)
26 #define bug printf("*********\n");
27 #define debug(x) cout<<"["<<x<<"]" <<endl;
28 #define FIN freopen("D://code//in.txt", "r", stdin);
29 #define IO ios::sync_with_stdio(false),cin.tie(0);
30
31 const double eps = 1e-8;
32 const LL mod = 1LL<<47;
33 const int maxn = 1e6 + 7;
34 const double pi = acos(-1);
35 const int inf = 0x3f3f3f3f;
36
37 int t;
38 int x1, yy1, w1, h1;
39 int x2, y2, w2, h2;
40 int x, y;
41 LL sum, ans;
42
43 int main() {
44     //FIN;
45     scanf("%d", &t);
46     while(t--) {
47         x = y = 0;
48         scanf("%d%d%d%d", &x1, &yy1, &w1, &h1);
49         scanf("%d%d%d%d", &x2, &y2, &w2, &h2);
50         sum = (LL)w1 * h1 + (LL)w2 * h2;
51         x = max(min(x1 + w1, x2 + w2) - max(x1, x2), 0);
52         y = max(min(yy1 + h1, y2 + h2) - max(yy1, y2), 0);
53         ans = (LL)x * y;
54         sum = sum - ans;
55         printf("%.2f\n", 1.0 * ans / sum);
56     }
57     return 0;
58 }

H题题目:

题意:

  以炉石传说为背景的题面,一个技能总共有n的伤害,可以将这n的伤害随机分配给敌方英雄和小兵,小兵的血量为m,英雄血量无穷,求杀死小兵的概率。

思路:

  一眼公式,只是因为没玩过炉石传说,不懂它的技能时如何产生伤害的,问了才知道,这个技能是一滴一滴血进行减少的,也就是每一点伤害可以给英雄也可以给小兵,所以总的可能行为2^n,要想小兵死亡,则至少有m点伤害作用在小兵身上,所以可能性为:

因为前段时间写过杭电多校一道题目(题目链接题解链接),题目是要求

又我们知道,因此我们本题可以借助那题的思路来写~(当然由于n,m的范围很小完全可以预处理出来所以的再求个前缀和。)

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long ll;
17 typedef pair<ll, ll> pll;
18 typedef pair<ll, int> pli;
19 typedef pair<int, ll> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long ull;
22
23 #define lson i<<1
24 #define rson i<<1|1
25 #define IO ios::sync_with_stdio(false),cin.tie(0);
26
27 const double eps = 1e-8;
28 const int mod = 1e9 + 7;
29 const int maxn = 1e3 + 7;
30 const double pi = acos(-1);
31
32 int t, block;
33 ll sum;
34 ll a[maxn], b[maxn], pw[maxn], inv[maxn];
35
36 struct node {
37     int l, r, id;
38     ll ans;
39     bool operator < (const node & x) const {
40         return (l - 1) / block == (x.l - 1) / block ? r < x.r : l < x.l;
41     }
42 }ask[maxn*100];
43
44 ll Mod_Pow(ll x, ll n) {
45     ll res = 1;
46     while(n > 0) {
47         if(n & 1) res = res * x % mod;
48         x = x * x % mod;
49         n >>= 1;
50     }
51     return res;
52 }
53
54 void init() {
55     a[1] = 1;
56     pw[0] = 1;
57     for(int i = 1; i < maxn; i++) {
58         pw[i] = (pw[i-1] * 2) % mod;
59         inv[i] = Mod_Pow(pw[i], mod - 2);
60     }
61     for(int i = 2; i < maxn; i++) a[i] = a[i-1] * i % mod;
62     for(int i = 1; i < maxn; i++) b[i] = Mod_Pow(a[i], mod - 2);
63 }
64
65 ll C(int n, int m) {
66     if(n < 0 || m < 0 || m > n) return 0;
67     if(m == 0 || m == n) return 1;
68     return a[n] * b[n-m] % mod * b[m] % mod;
69 }
70
71 int main() {
72     //FIN;
73     ios::sync_with_stdio(false);
74     init();
75     cin >>t;
76     block = sqrt(maxn);
77     sum = 1;
78     for(int i = 1; i <= t; i++) {
79         cin >>ask[i].l >>ask[i].r;
80         ask[i].r--;
81         ask[i].id = i;
82     }
83     sort(ask + 1, ask + t + 1);
84     for(int i = 1, l = 1, r = 0; i <= t; i++) {
85         while(l < ask[i].l) sum = (2 * sum - C(l++, r) + mod) % mod;
86         while(l > ask[i].l) sum = ((sum + C(--l, r)) * b[2]) % mod;
87         while(r < ask[i].r) sum = (sum + C(l, ++r)) % mod;
88         while(r > ask[i].r) sum = (sum - C(l, r--) + mod) % mod;
89         ask[ask[i].id].ans = ((pw[ask[i].l] - sum + mod) % mod * inv[ask[i].l]) % mod;
90     }
91     for(int i = 1; i <= t; i++) {
92         cout <<ask[i].ans <<endl;
93     }
94     return 0;
95 }

J题题目:

题意:

  每个人(i)都有一个跟随者(i+1),跟随者的跟随者也是这个人的跟随者,以此类推。你有m个蛋糕,你将这m个蛋糕随机给这n个人,如果你给某一个人,那么那个人和他的跟随者都会对你诚实,最后求诚实人数的期望。

思路:

  又是一眼公式题,但是化简极难……可能是我学的组合公式全学到狗身上去了吧,反正推了很久。

  我们知道,如果我们将蛋糕给i,那么剩下的m-1个蛋糕你随便给i+1~n的人,都会获得n-i的诚实人数,那么我们枚举等级最高的人,给他一个蛋糕,剩下的m-1个蛋糕随便给等级比他低的即可,不能给等级比他高的人,不然会重复计算。

  公式为:

  对于这个公式我们由我们可以推得C(m,n-1)+C(m,n-2)+C(m,n-3)+...+C(m,m+1)+C(m,m) =C(m+1,n),最后我们可以推得,是不是很神奇?

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long LL;
17 typedef pair<LL, LL> pLL;
18 typedef pair<LL, int> pli;
19 typedef pair<int, LL> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long uLL;
22
23 #define lson i<<1
24 #define rson i<<1|1
25 #define lowbit(x) x&(-x)
26 #define IO ios::sync_with_stdio(false),cin.tie(0);
27
28 const double eps = 1e-8;
29 const int mod = 1e9 + 7;
30 const int maxn = 1e6 + 7;
31 const double pi = acos(-1);
32
33 int t;
34 int inv[maxn];
35 LL n, m, ans;
36
37 LL Mod_Pow(LL x, LL n) {
38     LL res = 1;
39     while(n) {
40         if(n & 1) res = res * x % mod;
41         x = x * x % mod;
42         n >>= 1;
43     }
44     return res;
45 }
46
47 void init() {
48     inv[1] = 1;
49     for(int i = 2; i < maxn; i++) {
50         inv[i] = Mod_Pow(i, mod - 2);
51     }
52 }
53
54 int main() {
55     init();
56     scanf("%d", &t);
57     while(t--) {
58         scanf("%d%d", &n, &m);
59         if(m >= n) {
60             printf("%d\n", n);
61             continue;
62         }
63         ans = (m * (n + 1) % mod) * inv[m+1] % mod;
64         printf("%lld\n", ans);
65     }
66     return 0;
67 }

原文地址:https://www.cnblogs.com/Dillonh/p/9539429.html

时间: 2024-10-07 14:56:11

第九届福建省大学生程序设计竞赛 2018.8.26组队训练赛的相关文章

FZU2295 Human life:网络流-最大权闭合子图-二进制优化-第九届福建省大学生程序设计竞赛

目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门 ?原题目描述在最下面. ?题意就是很裸的最大权闭合子图. ?推荐阅读:胡伯涛<最小割模型在信息学竞赛中的应用> ?完完全全的模板题:新疆大学五月月赛-D-勤奋的杨老师 ?本题题意:m(50)个任务,n个技能.完成每个任务由相应的收益,完成每个任务前必须学一些技能.有些技能由先修技能. ?有些任务不能同时完成. Solution: ?训练

第六届福建省大学生程序设计竞赛不完全题解

昨天自己队做了一下第六届福建省赛,感觉有些蒙,赛后补了几道题,能力有限,一共只出A了7道题 A题   Super Mobile Charger 题目链接 http://acm.fzu.edu.cn/problem.php?pid=2212 水题 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int a[10005]; int b[10005]; int main(

(最短路)第七届福建省大学生程序设计竞赛 Problem J- X

Problem Description X is a fully prosperous country, especially known for its complicated transportation networks. But recently, for the sake of better controlling by the government, the president Fat Brother thinks it's time to close some roads in o

RunningMan【第六届福建省大学生程序设计竞赛-重现赛】

RunningMan Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: 2221 64-bit integer IO format: %I64d      Java class name: Main Prev Submit Status Statistics Discuss Next ZB loves watching RunningMan! There's a ga

第八届福建省大学生程序设计竞赛-重现赛

第八届福建省大学生程序设计竞赛-重现赛 B   计算几何 题意:问两个三角形是相交.包含还是相离. tags:套板子..求出相交的面积,再判断一下 /* 多边形相交面积模板 */ #define maxn 510 const double eps=1E-8; int sig(double d){ return(d>eps)-(d<-eps); } struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} b

&quot;高教社杯&quot;第三届福建省大学生程序设计竞赛

 A.Problem 2102 Solve equation Accept: 1032    Submit: 2471 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description You are given two positive integers A and B in Base C. For the equation: A=k*B+d We know there always existing many non-

ZZUOJ-1195-(郑州大学第七届ACM大学生程序设计竞赛E题)

1195: OS Job Scheduling Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 106  Solved: 35 [Submit][Status][Web Board] Description OS(Operating System) is to help user solve the problem, such as run job(task).A multitasking OS is one that can simultaneo

ZZUOJ-1195-OS Job Scheduling(郑州大学第七届ACM大学生程序设计竞赛E题)

1195: OS Job Scheduling Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 106  Solved: 35 [Submit][Status][Web Board] Description OS(Operating System) is to help user solve the problem, such as run job(task).A multitasking OS is one that can simultaneo

第四届福建省大学生程序设计竞赛

FZU2140  Forever 0.5 题意:构造一些点使得满足一些条件 思路:把1个点放在(0,0)然后n-1点平均分在60度的圆弧上,这样也就是有n-1对点距离为1.0 因为是60°所以n-1里面有一对点距离是1.0 #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<map> #include<cmath> #in