Codeforces Edu Round 63 (Rated for Div. 2)

感觉现在Edu场比以前的难多了……


A:

温暖人心

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 3e5 + 10;
42 int n;
43 char s[maxn];
44 
45 int main()
46 {
47     scanf("%d", &n);
48     scanf("%s", s + 1);
49     rep0(i, 1, n)
50     {
51         if (s[i] > s[i + 1])
52             return cout << "YES" << endl << i << " " << i + 1, 0;
53     }
54     puts("NO");
55     return 0;
56 }
View Code

B:

数前n-10个数里几个8几个非8就完事了,正确性显然

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 1e5 + 10;
42 char s[maxn];
43 int n, numOfEight = 0, re = 0;
44 
45 int main()
46 {
47     scanf("%d", &n);
48     scanf("%s", s + 1);
49     rep1(i, 1, n - 10)
50     if (s[i] == '8') numOfEight++; else re++;
51     if (numOfEight > re) puts("YES"); else puts("NO");
52     return 0;
53 }
View Code

C:

计算所有时间区间gcd,找是否存在p能整除gcd,正确性显然

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 3e5 + 10;
42 int n, m;
43 ll s, currX, lastX, currP, ansPos = 0, gcd;
44 
45 int main()
46 {
47     scanf("%d%d", &n, &m);
48     rep1(i, 1, n)
49     {
50         scanf("%lld", &currX);
51         if (i == 1) s = currX;
52         else if (i == 2) gcd = currX - lastX;
53         else gcd = __gcd(gcd, currX - lastX);
54         lastX = currX;
55     }
56     rep1(i, 1, m)
57     {
58         scanf("%lld", &currP);
59         if (!(gcd % currP)) ansPos = i;
60     }
61     if (!ansPos) puts("NO");
62     else printf("YES\n%lld %lld\n", s, ansPos);
63     return 0;
64 }
View Code

D:

dp,然而我想的是数据结构……

dp做法是:定义一维数组f[maxn],f[i]代表从当前位置往后取能取到的最大区间和;定义二维数组dp[2][maxn],dp[0][i]表示从当前位置往前取能取到的最大区间和,dp[1][i]表示在乘x的情况下,从当前位置能取到的最大区间和。转移显而易见。

有个坑点是ans初始化应该是0而不是LONG_LONG_MIN

 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define init(a,b) fill(begin(a),end(a),b)
28 #define sot(a,b) sort(a+1,a+1+b)
29 #define rep1(i,a,b) for(int i=a;i<=b;++i)
30 #define rep0(i,a,b) for(int i=a;i<b;++i)
31 #define repa(i,a) for(auto &i:a)
32 #define eps 1e-8
33 #define int_inf 0x3f3f3f3f
34 #define ll_inf 0x7f7f7f7f7f7f7f7f
35 #define lson curPos<<1
36 #define rson curPos<<1|1
37 /* namespace */
38 using namespace std;
39 /* header end */
40 
41 const int maxn = 3e5 + 10;
42 ll a[maxn], f[maxn], dp[2][maxn], x, ans = 0;
43 int n;
44 
45 int main()
46 {
47     scanf("%d%lld", &n, &x);
48     rep1(i, 1, n) scanf("%lld", &a[i]);
49     f[n + 1] = 0;
50     for (int i = n; i >= 1; i--)
51         f[i] = max(a[i], f[i + 1] + a[i]);
52     rep1(i, 1, n)
53     {
54         dp[0][i] = max(a[i], dp[0][i - 1] + a[i]);
55         dp[1][i] = a[i] * x;
56         if (max(dp[0][i - 1], dp[1][i - 1]) > 0)
57             dp[1][i] += max(dp[0][i - 1], dp[1][i - 1]);
58         ans = max(ans, max(dp[0][i], dp[1][i] + f[i + 1]));
59         ans = max(ans, dp[1][i]);
60     }
61     printf("%lld\n", ans);
62     return 0;
63 }
View Code

E:

edu都有交互了,简直丧心病狂。看到形如a0+a1*x+a2*x^2+...+an*x^n的多项式就很自然会想到拉格朗日插值法。

  1 /* basic header */
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <string>
  6 #include <cstring>
  7 #include <cmath>
  8 #include <cstdint>
  9 #include <climits>
 10 #include <float.h>
 11 #include <complex>
 12 /* STL */
 13 #include <vector>
 14 #include <set>
 15 #include <map>
 16 #include <queue>
 17 #include <stack>
 18 #include <algorithm>
 19 #include <array>
 20 #include <iterator>
 21 /* define */
 22 #define ll long long
 23 #define dou double
 24 #define pb emplace_back
 25 #define mp make_pair
 26 #define fir first
 27 #define sec second
 28 #define init(a,b) fill(begin(a),end(a),b)
 29 #define sot(a,b) sort(a+1,a+1+b)
 30 #define rep1(i,a,b) for(int i=a;i<=b;++i)
 31 #define rep0(i,a,b) for(int i=a;i<b;++i)
 32 #define repa(i,a) for(auto &i:a)
 33 #define eps 1e-8
 34 #define int_inf 0x3f3f3f3f
 35 #define ll_inf 0x7f7f7f7f7f7f7f7f
 36 #define lson curPos<<1
 37 #define rson curPos<<1|1
 38 /* namespace */
 39 using namespace std;
 40 /* header end */
 41 
 42 const int MOD = 1e6 + 3;
 43 
 44 //定义mod P意义下的运算
 45 #include <unordered_map>
 46 struct Mod
 47 {
 48     const ll mod, sqrtMod;
 49     Mod(ll p): mod(p), sqrtMod(sqrt(p) + 0.5) {}
 50 
 51     ll add(ll a, ll b)const
 52     {
 53         return ((a + b) % mod + mod) % mod;
 54     }
 55 
 56     ll mul(ll a, ll b)const
 57     {
 58         while (a < 0) a += mod; while (b < 0) b += mod;
 59         return a * b % mod;
 60     }
 61 
 62     ll pow(ll a, ll b)const
 63     {
 64         ll ret = 1;
 65         for (a %= mod; b; b >>= 1, a = mul(a, a))
 66             if (b & 1)
 67                 ret = mul(ret, a);
 68         return ret;
 69     }
 70 
 71     //乘法逆元
 72     ll inv(ll a)const
 73     {
 74         while (a < 0) a += mod;
 75         return pow(a, mod - 2);
 76     }
 77 
 78     ll log(ll a, ll b)const
 79     {
 80         unordered_map<ll, ll>x;
 81         for (ll i = 0, e = 1; i <= sqrtMod; i++, e = mul(e, a))
 82         {
 83             if (!x.count(e))
 84                 x[e] = i;
 85         }
 86         for (ll i = 0, v = inv(pow(a, sqrtMod)); i <= sqrtMod; i++, b = mul(b, v))
 87         {
 88             if (x.count(b))
 89                 return i * sqrtMod + x[b];
 90         }
 91         return -1;
 92     }
 93 } m(MOD);
 94 
 95 //拉格朗日插值法
 96 #define X real()
 97 #define Y imag()
 98 class Lagrange
 99 {
100 public:
101     static vector<ll> solve(vector<complex<ll>> p)
102     {
103         vector<ll> ret(p.size()), sum(p.size());
104         ret[0] = p[0].Y, sum[0] = 1;
105         rep0(i, 1, p.size())
106         {
107             for (int j = p.size() - 1; j >= i; j--)
108                 p[j].imag(m.mul(p[j].Y - p[j - 1].Y, m.inv(p[j].X - p[j - i].X)));
109             for (int j = i; ~j; j--)
110             {
111                 sum[j] = m.add(j ? sum[j - 1] : 0, -m.mul(sum[j], p[i - 1].X));
112                 ret[j] = m.add(ret[j], m.mul(sum[j], p[i].Y));
113             }
114         }
115         return ret;
116     }
117 };
118 
119 int main()
120 {
121     vector<complex<ll>>v;
122     for (ll i = 0, x; i < 11; i++)
123     {
124         printf("? %lld\n", i);
125         fflush(stdout);
126         scanf("%lld", &x);
127         if (!x)
128             return printf("! %lld\n", i), 0;
129         v.push_back({i, x % m.mod});
130     }
131     vector<ll> ret = Lagrange().solve(v);
132     for (ll i = 0; i < m.mod; i++)
133     {
134         ll sum = 0;
135         for (ll j = 0, x = 1; j < ret.size(); j++, x = m.mul(x, i))
136             sum = m.add(sum, m.mul(x, ret[j]));
137         if (sum == 0)
138             return printf("! %lld\n", i), 0;
139     }
140     puts("! -1");
141     return 0;
142 }
View Code

F:

给定一个无向图,满足边双联通。要求删去尽量多的边,使得剩下的子图在包含原图所有节点的情况下仍然满足边双。输出子图。

这里给个神仙用tarjan的做法,从67行开始就有点玄幻了……

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 using namespace std;
  5 
  6 const int MAXN = 10;
  7 
  8 struct node
  9 {
 10     int v, next, use;
 11 } edge[MAXN << 2];
 12 
 13 bool bridge[MAXN];
 14 int low[MAXN], dfn[MAXN], vis[MAXN];
 15 int head[MAXN], pre[MAXN], ip, sol, Count, u[MAXN], v[MAXN], n, m, p[MAXN], i, viss[MAXN], s, ans = -1, j, t[MAXN];
 16 
 17 void init(void)
 18 {
 19     memset(head, -1, sizeof(head));
 20     memset(vis, false, sizeof(vis));
 21     memset(bridge, false, sizeof(bridge));
 22     Count = sol = ip = 0;
 23 }
 24 
 25 void addEdge(int u, int v)
 26 {
 27     edge[ip].v = v;
 28     edge[ip].use = 0;
 29     edge[ip].next = head[u];
 30     head[u] = ip++;
 31 }
 32 bool flag;
 33 void tarjan(int u)
 34 {
 35     vis[u] = 1;
 36     dfn[u] = low[u] = Count++;
 37     for (int i = head[u]; i != -1; i = edge[i].next)
 38     {
 39         if (!edge[i].use)
 40         {
 41             edge[i].use = edge[i ^ 1].use = 1;
 42             int v = edge[i].v;
 43             if (!vis[v])
 44             {
 45                 pre[v] = u;
 46                 tarjan(v);
 47                 low[u] = min(low[u], low[v]);
 48                 if (dfn[u] < low[v])
 49                 {
 50                     sol++;
 51                     flag = 0;
 52                 }
 53             }
 54             else if (vis[v] == 1)
 55             {
 56                 low[u] = min(low[u], dfn[v]);
 57             }
 58         }
 59     }
 60     vis[u] = 2;
 61 }
 62 int main(void)
 63 {
 64     scanf("%d %d", &n, &m); 
 65     for (i = 1; i <= m; i++) scanf("%d %d", &u[i], &v[i]);
 66     for (i = 1; i <= m; i++) p[i] = i;
 67     for (int jo = 1; jo <= 20000; jo++)
 68     {
 69         //随机建图
 70         for (i = 1; i <= 100; i++) 
 71         {
 72             int x = rand() % m + 1, y = rand() % m + 1;
 73             swap(p[x], p[y]);
 74         }
 75         memset(viss, 0, sizeof(viss));
 76         for (i = 1; i <= m; i++)
 77         {
 78             init();
 79             viss[i] = 1;
 80             for (j = 1; j <= m; j++)
 81                 if (!viss[j])
 82                 {
 83                     addEdge(u[p[j]], v[p[j]]);
 84                     addEdge(v[p[j]], u[p[j]]);
 85                 }
 86             flag = 1;
 87             tarjan(1);
 88             for (j = 1; j <= n; j++)
 89                 if (vis[j] == 0)
 90                     flag = 0;
 91             if (!flag)
 92                 viss[i] = 0;
 93         }
 94         s = 0;
 95         for (i = 1; i <= m; i++)
 96             if (viss[i] == 1)
 97                 s++;
 98         if (ans < s)
 99         {
100             ans = s;
101             int y = 0;
102             for (i = 1; i <= m; i++)
103                 if (viss[i] == 0)
104                     t[++y] = p[i];
105         }
106     }
107     cout << m - ans << endl;
108     for (i = 1; i <= m - ans; i++)
109         printf("%d %d\n", u[t[i]], v[t[i]]);
110     return 0;
111 }
View Code

 

转载于:https://www.cnblogs.com/JHSeng/p/10758314.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值