2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution

A. Numbers

Unsolved.

B. Broken Watch

Solved.

题意:

一个圆盘上,有等分的n块区域,有三根指针,当三根指针分别位于两块区域的交界处时

指针的三点相连会形成一个三角形,求有多少个三角包含三指针的起点(即交汇处)

思路:

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef unsigned long long ull;
 6 typedef long long ll;
 7
 8 ll A, B, C, n;
 9
10 int main()
11 {
12     while(~scanf("%lld %lld %lld %lld" ,&A, &B, &C, &n))
13     {
14         ull tmp = (n + 1) / 2;
15         tmp -= 2;
16         ull a = n, b = n - 1, c = n - 2;
17         if(a % 2 == 0) a /= 2;
18         else if(b % 2 == 0) b /= 2;
19         else if(c % 2 == 0) c /= 2;
20
21         if(a % 3 == 0) a /= 3;
22         else if(b % 3 == 0) b /= 3;
23         else if(c % 3 == 0) c /= 3;
24
25         ull ans = a * b * c;
26
27         ans -= n * (tmp * (tmp + 1) / 2);
28
29         if(A != B && B != C && C != A) ans = ans * 6;
30         else if(A != B || B != C || C != A) ans = ans * 3;
31
32         printf("%llu\n", ans);
33     }
34     return 0;
35 }

C. Tree

Solved.

题意:

一棵树中,有些点是黑点,有些点是白点,求恰选择m个黑点

使得黑点中任意两点的最长距离最短

思路:

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 110;
 6
 7 struct Edge{
 8     int to, nxt;
 9     Edge(){}
10     Edge(int to, int nxt): to(to), nxt(nxt){}
11 }edge[maxn << 1];
12
13 int n, m;
14 int p[maxn];
15 int vis[maxn];
16 int head[maxn], tot;
17
18 void Init(int n)
19 {
20     tot = 0;
21     for(int i = 1; i <= n; ++i) head[i] = -1;
22 }
23
24 void addedge(int u,int v)
25 {
26     edge[tot] = Edge(v, head[u]); head[u] = tot++;
27     edge[tot] = Edge(u, head[v]); head[v] = tot++;
28 }
29
30 int DFS(int u,int fa, int limit, int dis)
31 {
32     int res = p[u];
33     if(dis == limit) return res;
34     for(int i = head[u]; ~i; i = edge[i].nxt)
35     {
36         int v = edge[i].to;
37         if(!vis[v] || v == fa) continue;
38         res += DFS(v, u, limit, dis + 1);
39     }
40     return res;
41 }
42
43 bool check(int mid)
44 {
45     for(int i = 1; i <= n; ++i) vis[i] = 0;
46     queue<int>q;
47     q.push(1);
48     while(!q.empty())
49     {
50         int u = q.front();
51         q.pop();
52         vis[u] = 1;
53         if(DFS(u, -1, mid, 0) >= m) return true;
54         for(int i = head[u]; ~i; i = edge[i].nxt)
55         {
56             int v = edge[i].to;
57             if(vis[v]) continue;
58             q.push(v);
59         }
60     }
61     return false;
62 }
63
64 int main()
65 {
66     while(~scanf("%d %d", &n, &m))
67     {
68         Init(n);
69         for(int i = 1; i <= n; ++i) scanf("%d", p + i);
70         for(int i = 1, u, v; i < n; ++i)
71         {
72             scanf("%d %d", &u, &v);
73             addedge(u, v);
74         }
75         int l = 0, r = n;
76         int res = 0;
77         while(r - l >= 0)
78         {
79             int mid = (l + r) >> 1;
80             if(check(mid))
81             {
82                 r = mid - 1;
83                 res = mid;
84             }
85             else l = mid + 1;
86         }
87         printf("%d\n", res);
88     }
89     return 0;
90 }

D. Space Station

Unsolved.

E. Fishermen

Solved.

题意:

在一个二维平面,有有一些鱼,也有一些渔民,每个渔民有一个钓竿

渔民都在$x轴上,渔民可以钓到那条鱼的条件是它和鱼的曼哈顿距离小于等于钓竿长度$

思路:

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 2e5 + 10;
 6
 7 struct node{
 8     int l, r;
 9     node(){}
10     node(int l,int r): l(l), r(r){}
11     bool operator < (const node &b) const
12     {
13         if(l == b.l) return r < b.r;
14         else return l < b.l;
15     }
16 }arr[maxn];
17
18 struct qnode{
19     int pos, idx;
20     qnode(){}
21     qnode(int pos, int idx): pos(pos), idx(idx){}
22     bool operator < (const qnode &b) const
23     {
24         return pos < b.pos;
25     }
26 }brr[maxn];
27
28 int n, m, l;
29 int ans[maxn];
30
31 int main()
32 {
33     while(~scanf("%d %d %d", &n, &m, &l))
34     {
35         int pos = 0;
36         for(int i = 1; i <= n; ++i)
37         {
38             int x, y;
39             scanf("%d %d", &x ,&y);
40             if(y > l) continue;
41             int tmp = l - y;
42             arr[++pos] = node(x - tmp, x + tmp);
43         }
44         sort(arr + 1, arr + 1 + pos);
45         for(int i = 1; i <= m; ++i)
46         {
47             scanf("%d", &brr[i].pos);
48             brr[i].idx = i;
49         }
50         sort(brr + 1, brr + 1 + m);
51         priority_queue<int, vector<int>, greater<int> >q;
52         int cnt = 1;
53         for(int i = 1; i <= m; ++i)
54         {
55             while(cnt <= pos && brr[i].pos >= arr[cnt].l)
56             {
57                 q.push(arr[cnt++].r);
58             }
59             while(!q.empty() && q.top() < brr[i].pos)
60             {
61                 q.pop();
62             }
63             ans[brr[i].idx] = q.size();
64         }
65         for(int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
66     }
67     return 0;
68 }

F. Min Max Convert

Unsolved.

题意:

每一次可以将一段区间的所有值变成它原先的最大或最小值

求有没有一种操作方案使得序列A 变成 序列B 如果有输出操作方案

否则输出-1

G. Matrix Queries

Unsolved.

题意:

在一个$2^n \cdot 2^n 的矩形里面,刚开始都是白色,每一次可以把一行或者一列的颜色翻转$

求每次操作后矩阵的值

这样定义矩阵的值:

如果当前矩阵的所有颜色都相同,那么该矩阵的值为1

否则将当前矩阵等分为四个,当前矩阵的值就是四个小矩阵的值+1

H. Modern Djinn

Unsolved.

I. Inversion

Solved.

题意:

在一张图中,求有多少个点集,使得这个点集里面的任意两点没有边

不在点集里面的点至少有一条边连向点集中一点

思路:

我们考虑一条边 $(i, j) 那么定义在一个序列中(i, j) 为一个逆序对$

那么就是找上升子序列的个数

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef long long ll;
 6
 7 const int maxn = 1e2 + 10;
 8
 9 ll dp[maxn];
10 int G[maxn][maxn];
11 int n, m;
12
13 int main()
14 {
15     while(~scanf("%d %d", &n, &m))
16     {
17         memset(dp, 0, sizeof dp);
18         memset(G, 0, sizeof G);
19         for(int i = 1, u, v; i <= m; ++i)
20         {
21             scanf("%d %d", &u, &v);
22             G[u][v]++;
23             G[v][u]++;
24         }
25         dp[0] = 1 ;
26         for(int i = 1; i <= n + 1; ++i)
27         {
28             for(int j = 0; j < i; ++j)
29             {
30                 if(G[i][j]) continue;
31                 int flag = 1;
32                 for(int k = j + 1; k < i; ++k)
33                 {
34                     if(G[i][k] || G[j][k]) continue;
35                     else
36                     {
37                         flag = 0;
38                         break;
39                     }
40                 }
41                 dp[i] += flag * dp[j];
42             }
43         }
44         printf("%lld\n", dp[n + 1]);
45     }
46     return 0;
47 }

J. Rabbit vs Turtle

Unsolved.

K. Points and Rectangles

Solved.

题意:

两种操作

一种是往一个二维平面加入一个点

还有一种是加入一个矩阵

询问每次操作后有多少个$pair(x, R)$

$pair(x, R) 表示 点x 在 矩形R 内$

思路:

考虑CDQ分治

对于每个矩阵,可以拆成四个点分治

对于每个点,我们可以把矩形的四个角赋上权值

左上角 1

左下角 -1

右上角-1

右下角1

然后把矩阵往左和网上拓宽一个单位

那么对于每个点来说就是查询右下角的值

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define ll long long
  5 #define N 100010
  6 struct qnode
  7 {
  8     int tp, x, y, id; bool isleft;
  9     qnode () {}
 10     qnode (int tp, int x, int y, int id) : tp(tp), x(x), y(y), id(id) {}
 11     bool operator < (const qnode &other) const { return x < other.x || x == other.x && id < other.id; }
 12 }que[N << 2], tque[N << 2];
 13 int n, m, q, brr[N << 2];
 14 ll ans[N];
 15
 16 void Hash()
 17 {
 18     sort(brr + 1, brr + 1 + m);
 19     m = unique(brr + 1, brr + 1 + m) - brr - 1;
 20     for (int i = 1; i <= n; ++i) que[i].y = lower_bound(brr + 1, brr + 1 + m, que[i].y) - brr;
 21 }
 22
 23 namespace BIT
 24 {
 25     int a[N << 2];
 26     void init() { memset(a, 0, sizeof a); }
 27     void update(int x, int val)
 28     {
 29         for (; x <= m; x += x & -x)
 30         {
 31             if (val == 0) a[x] = 0;
 32             else a[x] += val;
 33         }
 34     }
 35     ll query(int x)
 36     {
 37         ll res = 0;
 38         for (; x; x -= x & -x)
 39             res += a[x];
 40         return res;
 41     }
 42 }
 43
 44 void CDQ1(int l, int r)
 45 {
 46     if (l == r) return;
 47     int mid = (l + r) >> 1;
 48     for (int i = l; i <= r; ++i)
 49     {
 50         tque[i] = que[i];
 51         if (i <= mid) tque[i].isleft = true;
 52         else tque[i].isleft = false;
 53     }
 54     sort(tque + l, tque + 1 + r);
 55     for (int i = l; i <= r; ++i)
 56     {
 57         if (tque[i].tp == 0 && tque[i].isleft == true) BIT::update(tque[i].y, 1);
 58         else if (tque[i].tp && tque[i].isleft == false)ans[tque[i].id] += BIT::query(tque[i].y) * tque[i].tp;
 59     }
 60     for (int i = l; i <= r; ++i) if (tque[i].tp == 0 && tque[i].isleft == true) BIT::update(tque[i].y, 0);
 61     CDQ1(l, mid), CDQ1(mid + 1, r);
 62 }
 63
 64 void CDQ2(int l, int r)
 65 {
 66     if (l == r) return;
 67     int mid = (l + r) >> 1;
 68     for (int i = l; i <= r; ++i)
 69     {
 70         tque[i] = que[i];
 71         if (i <= mid) tque[i].isleft = true;
 72         else tque[i].isleft = false;
 73     }
 74     sort(tque + l, tque + 1 + r, [](qnode a, qnode b) { return a.x > b.x || a.x == b.x && a.id < b.id; });
 75     for (int i = l; i <= r; ++i)
 76     {
 77         if (tque[i].tp != 0 && tque[i].isleft == true) BIT::update(tque[i].y, tque[i].tp);
 78         else if (tque[i].tp == 0 && tque[i].isleft == false) ans[tque[i].id] += BIT::query(m) - BIT::query(tque[i].y - 1);
 79     }
 80     for (int i = l; i <= r; ++i) if (tque[i].tp && tque[i].isleft == true) BIT::update(tque[i].y, 0);
 81     CDQ2(l, mid); CDQ2(mid + 1, r);
 82 }
 83
 84 int main()
 85 {
 86     while (scanf("%d", &q) != EOF)
 87     {
 88         n = 0; ans[0] = 0; m = 0;
 89         memset(ans, 0, sizeof ans);
 90         for (int i = 1, op, x[2], y[2]; i <= q; ++i)
 91         {
 92             scanf("%d%d%d", &op, x, y);
 93             brr[++m] = y[0]; brr[++m] = y[0] - 1;
 94             if (op == 1) que[++n] = qnode(0, x[0], y[0], i);
 95             else
 96             {
 97                 scanf("%d%d", x + 1, y + 1);
 98                 brr[++m] = y[1]; brr[++m] = y[1] - 1;
 99                 que[++n] = qnode(1, x[0] - 1, y[0] - 1, i);
100                 que[++n] = qnode(1, x[1], y[1], i);
101                 que[++n] = qnode(-1, x[0] - 1, y[1], i);
102                 que[++n] = qnode(-1, x[1], y[0] - 1, i);
103             }
104         }
105         Hash(); BIT::init();
106         CDQ1(1, n); CDQ2(1, n);
107         for (int i = 1; i <= q; ++i) printf("%lld\n", ans[i] += ans[i - 1]);
108     }
109     return 0;
110 }

原文地址:https://www.cnblogs.com/Dup4/p/10055176.html

时间: 2024-10-08 11:31:39

2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution的相关文章

2018-2019 ICPC Northwestern European Regional Programming Contest (NWERC 2018)

J题队友犯了初始化的错,白给6发,本来能1A的 B: solver:lzh.czq 就是个拓扑排序 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ff first 4 #define ss second 5 #define mp make_pair 6 typedef long long ll; 7 typedef pair<int, int> pii; 8 9 vector<int> g[400

2004-2005 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2004)

https://codeforc.es/gym/101461 5题结束了,可能是只打了3个小时吧.要是E试试Java8去用高精浮点二分,或者坚持读下来发现F是个割点模板题?以后可能远古场还是不打了,要拉2015年以内的. D - City Game 悬线法求最大非1子矩阵,根据up[i][j]=(g[i][j]==0)?0:up[i-1][j]+1预处理出悬线.然后每一行用单调栈扫.注意悬线法,某个元素被弹出之后,弹出他的元素会继承他的管辖范围!所以当时的办法是弄两个栈,一个栈存单调递增的悬线下

2019-2020 ICPC Southwestern European Regional Programming Contest (SWERC 2019-2020)

J想到了卡特兰数,也想到要按最小值分割数组,丢给队友之后两个人都没做出来,傻了 题目链接:https://codeforces.com/gym/102501 B: solver:czq 1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define pb emplace_back 6 #define mp make_pair 7 #define eps 1e-8 8

2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016) 个人题解

Problem C Careful Ascent 可怜的我们被卡在了签到题上,当时用的二分来做,结果速度的左右区间写成了[0,1e32],而改成[-1e32,1e32]就通过了,哎-,怎么就没想到去改一下区间的范围呢. 下面是正常的数学解法,类似于解一元一次方程. #include <iostream> using namespace std; typedef long long ll; ll x,y,n; ll a,b;double c; int main(){ cin>>x&g

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Krak&#243;w

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik's RectangleProblem B: What does the fox say?Problem C: Magical GCDProblem D: SubwayProblem E: EscapeProblem F: DraughtsProblem G: History courseProblem H: C

(寒假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: "luowentaoaa" catalog: true tags: mathjax: true - codeforces 传送门 付队! B.Baby Bites (签到模拟) 按照题意模拟就行了 int a[maxn]; string s; int main() { std::ios::syn

训练20191007 2017-2018 ACM-ICPC Latin American Regional Programming Contest

2017-2018 ACM-ICPC Latin American Regional Programming Contest 试题地址:http://codeforces.com/gym/101889 总体情况 总共通过7题CEFGHIJ.其中我完成HIJ三题.纯属被大佬带飞系列. 解题报告 H - Hard choice 签到题 #include <bits/stdc++.h> using namespace std; int a1,b1,c1,a2,b2,c2; int main() {

2019 ACM ICPC 南京站 H. Prince and Princess

题意 王子想要娶公主,但是需要完成一个挑战:在一些房间中找出公主在哪. 每个房间有一个人,他们彼此知道谁在哪个房间.可以问他们三种问题: 你是谁? 在某个房间是谁? 公主在哪个房间? 有三类人,一类一定说真话,一类一定说假话,一类可能说真话可能说假话. 王子知道这三类人的人数分别为 \(a\), \(b\), \(c\),求能否通过问一些问题找到公主在哪,如果能,输出最少需要的问题数. 思路 第三类人有可能说假话,因此最坏情况就是说假话,所以把他们视为第二类人. 首先问所有人第三个问题,那么最坏

2017-2018 ACM-ICPC Latin American Regional Programming Contest Solution

A - Arranging tiles 留坑. B - Buggy ICPC 题意:给出一个字符串,然后有两条规则,如果打出一个辅音字母,直接接在原字符串后面,如果打出一个元音字母,那么接在原来的字符串后面之后再翻转整个字符串,在这两条规则之下,求有多少种打印给定字符串的方法 思路:如果第一个字符是辅音,那么答案为0 如果全是辅音或全是元音,那么答案为1 如果只有一个辅音,答案为len 否则是最中间两个元音中间的辅音字符个数+1 1 #include <bits/stdc++.h> 2 3 u