D. Denouncing Mafia

给定一颗树,然后给定\(k\)个起点,对于每个起点来说,从该点到根节点的一条链都会被染色,求最多有几个点会被染色

\(3 \leq n \leq 1e5, 1 \leq k \leq n\)

题解

  • 我们贪心的来看,起点一定会选择在叶子节点,假设叶子节点的数量为\(cnt\),所以如果\(k \geq cnt\),那么答案一定为\(n\)
  • 否则我们可以长链剖分,将每条链剖出来后排序取前\(k\)条链即可
const int N = 1e5 + 10, M = 4e5 + 10;

int n, k;
vector<int> g[N];
int hson[N], dep[N], mx_dep[N], fa[N], sz[N];
int l[N], r[N], id[N], idx, top[N];
int tot, w[N]; void dfs1(int u, int par)
{
sz[u] = 1;
hson[u] = -1;
fa[u] = par;
mx_dep[u] = dep[u] = dep[par] + 1;
for (auto v : g[u])
{
if (v == par)
continue;
dfs1(v, u);
sz[u] += sz[v];
mx_dep[u] = max(mx_dep[u], mx_dep[v]);
if (hson[u] == -1 || mx_dep[v] > mx_dep[hson[u]])
hson[u] = v;
}
} void dfs2(int u, int head)
{
top[u] = head;
l[u] = ++idx;
id[idx] = u;
if (hson[u] != -1)
dfs2(hson[u], head);
for (auto v : g[u])
{
if (v != fa[u] && v != hson[u])
dfs2(v, v);
}
r[u] = idx;
} void solve()
{
cin >> n >> k;
for (int i = 2; i <= n; ++i)
{
int u;
cin >> u;
g[u].push_back(i);
g[i].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
int cnt_son = 0;
for (int i = 1; i <= n; ++i)
{
if (sz[i] == 1)
{
cnt_son++;
w[++tot] = dep[i] - dep[top[i]] + 1;
}
}
if (k >= cnt_son)
{
cout << n << endl;
return;
}
sort(w + 1, w + tot + 1, greater<int>());
int ans = 0;
for (int i = 1; i <= k; ++i)
ans += w[i];
cout << ans << endl;
}

L. Less Coin Tosses

给定\(n, 2 \leq n \leq 1e18\),将\(2^n\)个二进制字符串分别分配给两个人,使得两个人获胜的概率相同的情况下未被分配的字符串数量最少

题解

  • 显然只要某一次分配的字符串中\(1\)的个数相同,那么两个人获胜的胜率能够始终相同

  • 所以答案为\(\sum (C_n^i \& 1==1)\)

  • 显然对于组合数的奇偶性,我们知道结论:若\((n \& k==k)\),则\(C_n^k\)为奇数,否则为偶数

  • 也就是说如果\(k\)的二进制是\(n\)的二进制的子集,那么答案贡献\(+1\)

  • 那么显然答案为\(n\)的二进制中\(1\)个数为\(x\),答案为\(2^x\)

const int N = 2e5 + 10, M = 4e5 + 10;

int n;

void solve()
{
cin >> n;
int x = __builtin_popcountll(n);
cout << (1ll << x) << endl;
}

M. Maratona Brasileira de Popcorn

题解

  • 考虑二分答案
  • \(check\)时检查需要几个人才能将所有的玉米吃完,然后与原有人数比较即可
const int N = 2e6 + 10;
int n,m,cnt;
int a[N]; bool check(int mid)
{
int w=1;
int x=mid*cnt;
for(int i=1;i<=n;)
{
if(a[i]-x<=0)
{
x-=a[i];
i++;
}
else
{
x=mid*cnt;
w++;
if(w>m) return false;
}
}
if(w>m ) return false;
else return true;
} void solve()
{
cin>>n>>m>>cnt;
for(int i=1;i<=n;i++) cin>>a[i];
int l=0,r=2e15;
while(l<=r)
{
int mid=l+r>>1;
if(check(mid)) r=mid-1;
else l=mid+1;
}
cout<<l<<endl;
}

J. Jar of Water Game

题解

  • 模拟即可
  • 注意细节:
  1. 拿到鬼牌后不能立刻传递
  2. 一开始的时候有可能已经存在获胜的玩家
  3. 每次判断胜利条件在传递牌之后,判断所有队伍是否胜利
const int N = 1e2 + 10, M = 4e5 + 10;

int n, k;
map<char, int> mp[N];
string cmp = "A23456789DQJK"; void solve()
{
cin >> n >> k;
for (int i = 1; i <= n; ++i)
{
string s;
cin >> s;
for (auto ch : s)
mp[i][ch]++;
if (i == k)
mp[i]['W']++;
}
int now = k;
bool flag = true;
int cur = 4;
while (true)
{
int nxt = now + 1;
if (nxt > n)
nxt = 1;
if (mp[now]['W'] > 0 && flag == false)
mp[nxt]['W']++, mp[now]['W']--, flag = true;
else
{
if (mp[now]['W'] > 0 && flag == true)
flag = false;
int mi = INF;
char ch;
for (auto [x, y] : mp[now])
{
if (y == 0)
continue;
if (x == 'W')
continue;
if (y < mi)
{
mi = y;
ch = x;
}
else if (y == mi)
{
if (cmp.find(x) < cmp.find(ch))
ch = x;
}
}
mp[now][ch]--;
mp[nxt][ch]++;
}
int ans = -1;
char ans_ch;
for (int i = 1; i <= n; ++i)
{
int cnt = 0;
bool ok = false;
char c;
for (auto [x, y] : mp[i])
{
cnt += (y > 0);
if (y == 4)
{
ok = true;
c = x;
}
}
if (ok && cnt == 1)
{
if (ans == -1)
{
ans = i;
ans_ch = c;
}
else if (cmp.find(c) < cmp.find(ans_ch))
{
ans = i;
ans_ch = c;
}
}
}
if (ans != -1)
{
cout << ans << endl;
return;
}
now = nxt;
}
}

A. Artwork

题解

  • \(O(n^2)\)将所有相交的监控用并查集合并,然后并查集中维护四种信息:是否与左墙接触\(left\),\(right\),\(up\),\(down\)
  • 然后判断是否有监控集合同时接触左墙和右墙,上墙和下墙,左墙和上墙,右墙和下墙之一即可
const int N = 1e4 + 10;
const int K = 1010;
int n, m, k, x[K], y[K], R[K];
bool f[K][5]; //up 1 down 2 left 3 right 4
const int UP = 1;
const int DOW = 2;
const int LE = 3;
const int RI = 4; bool check(int i){
return ((f[i][UP] && f[i][LE]) || (f[i][UP] && f[i][DOW]) || (f[i][LE] && f[i][RI]) || (f[i][RI] && f[i][DOW]));
} bool xiangjiao(int e1, int e2){
int dis=(x[e1]-x[e2])*(x[e1]-x[e2])+(y[e1]-y[e2])*(y[e1]-y[e2]);
int rr=(R[e1]+R[e2])*(R[e1]+R[e2]);
return dis<=rr;
} int fa[K]; int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
} void merg(int a, int b){
a = find(a);
b = find(b);
if(a == b) return;
f[b][UP] |= f[a][UP];
f[b][DOW] |= f[a][DOW];
f[b][LE] |= f[a][LE];
f[b][RI] |= f[a][RI];
fa[a] = b;
} void solve()
{
for(int i = 1;i < K;i++) fa[i] = i;
bool ans = false;
cin >> m >> n >> k;
for(int i = 1;i <= k;i++){
cin >> x[i] >> y[i] >> R[i];
if(x[i] - R[i] <= 0) f[i][UP] = true;
if(x[i] + R[i] >= m) f[i][DOW] = true;
if(y[i] - R[i] <= 0) f[i][LE] = true;
if(y[i] + R[i] >= n) f[i][RI] = true; if(check(i)) ans = true;
} if(ans){
cout << "N";
return;
} for(int i = 1;i <= k;i++){
for(int j = i + 1;j <= k;j++){
if(xiangjiao(i, j)){
merg(i, j);
if(check(find(j))){
cout << "N";
return;
}
}
}
} cout << "S";
}

F. Forests in Danger

给定\(n\)条平行于\(x\)轴或\(y\)轴的线段,每条线段能够覆盖的范围是一个矩阵,线段上每个点到矩阵边的最小距离都为\(r\),给定一块矩阵区域\(p\),请你确定一个最小的\(r\),能够使得\(n\)条线段产生的矩阵与矩阵\(p\)的重合部分的面积至少是矩阵\(p\)面积的\(\%P\)

题解:二分答案 + 矩形面积并

  • 显然二分答案
  • \(check\)时我们可以求出每个矩阵与矩阵\(p\)的交,交集同样也是一个矩阵
  • 然后对每一个交的矩阵求矩形面积并即可,最后和矩阵\(p\)的面积比较一下即可
  • \(tips\):利用线段树计算矩形的长时,需要对长度\(-1\),因为\([2,5]\)的长度在计算矩形面积时应该为\(3\),但是线段树中会返回\(4\)
const int N = 2e5 + 10, M = 4e5 + 10;

int n, P, x3, x4, y3, y4, m = 2e5 + 5;
struct Line
{
int x1, y1, x2, y2;
} line[N];
struct Mat : Line
{
} mat[N]; struct info
{
int mi, cnt;
friend info operator+(const info &a, const info &b)
{
info c;
if (a.mi == b.mi)
{
c.mi = a.mi;
c.cnt = a.cnt + b.cnt;
}
else if (a.mi < b.mi)
{
c.mi = a.mi;
c.cnt = a.cnt;
}
else
{
c.mi = b.mi;
c.cnt = b.cnt;
}
return c;
}
info(int mi = 0, int cnt = 0) : mi(mi), cnt(cnt) {}
};
struct SEG
{
int lazy;
info val;
} seg[N << 2]; void up(int id)
{
seg[id].val = seg[lson].val + seg[rson].val;
} void settag(int id, int tag)
{
seg[id].val.mi += tag;
seg[id].lazy += tag;
} void down(int id)
{
if (seg[id].lazy == 0)
return;
settag(lson, seg[id].lazy);
settag(rson, seg[id].lazy);
seg[id].lazy = 0;
} void build(int id, int l, int r)
{
seg[id].lazy = 0;
if (l == r)
{
seg[id].val = info(0, 1);
return;
}
int mid = l + r >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
up(id);
} void modify(int id, int l, int r, int ql, int qr, int val)
{
if (ql <= l && r <= qr)
{
settag(id, val);
return;
}
down(id);
int mid = l + r >> 1;
if (qr <= mid)
modify(lson, l, mid, ql, qr, val);
else if (ql > mid)
modify(rson, mid + 1, r, ql, qr, val);
else
{
modify(lson, l, mid, ql, qr, val);
modify(rson, mid + 1, r, ql, qr, val);
}
up(id);
} bool check(int r)
{
build(1, 1, m);
vector<array<int, 4>> evt;
vector<int> vec;
for (int i = 1; i <= n; ++i)
{
auto [x1, y1, x2, y2] = line[i];
mat[i] = {x1 - r, y1 - r, x2 + r, y2 + r};
}
for (int i = 1; i <= n; ++i)
{
auto [x1, y1, x2, y2] = mat[i];
int lx = max(x1, x3), ly = max(y1, y3);
int rx = min(x2, x4), ry = min(y2, y4);
if (lx < rx && ly < ry)
{
// 别忘记右端点 -1
evt.push_back({ly, -1, lx, rx - 1}); // 入边
evt.push_back({ry, 1, lx, rx - 1}); // 出边
}
}
sort(all(evt));
int ans = 0;
int sum = seg[1].val.cnt;
int preY = 0;
for (auto [y, op, l, r] : evt)
{
int len = sum;
if (seg[1].val.mi == 0)
len -= seg[1].val.cnt;
ans += (y - preY) * len;
if (op == -1)
modify(1, 1, m, l, r, 1);
else
modify(1, 1, m, l, r, -1);
preY = y;
}
int area = (x4 - x3) * (y4 - y3);
return ans * 100 >= area * P;
} void solve()
{
cin >> n;
for (int i = 1; i <= n; ++i)
{
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
line[i] = {x1 + 1, y1 + 1, x2 + 1, y2 + 1};
}
cin >> P;
cin >> x3 >> y3 >> x4 >> y4;
x3++, y3++, x4++, y4++;
int l = 0, r = 1e9;
while (l <= r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid - 1;
else
l = mid + 1;
}
cout << l << endl;
}

2019-2020 ACM-ICPC Brazil Subregional Programming Contest的更多相关文章

  1. (寒假GYM开黑)2018-2019 ACM-ICPC Brazil Subregional Programming Contest

    layout: post title: 2018-2019 ACM-ICPC Brazil Subregional Programming Contest author: "luowenta ...

  2. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest PART (10/13)

    $$2018-2019 ACM-ICPC Brazil Subregional Programming Contest$$ \(A.Slackline\ Adventure\) \(B.Marbles ...

  3. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest (11/13)

    \(2019-2020\ ACM-ICPC\ Brazil\ Subregional\ Programming\ Contest\) \(A.Artwork\) 并查集,把检测区域能在一起的检测器放在 ...

  4. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest

    A:留坑 B:二维sg函数,特判边界情况 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) / ...

  5. Gym.101908 Brazil Subregional Programming Contest(寒假自训第六场)

    这几天睡眠时间都不太够,室友晚上太会折腾了,感觉有点累,所以昨天的题解也没写,看晚上能不能补起来. B . Marbles 题意:给定N组数(xi,yi),玩家轮流操作,每次玩家可以选择其中一组对其操 ...

  6. 2013-2014 ACM-ICPC Brazil Subregional Programming Contest 题解

    [题目链接] 这场比赛题面英文都好长... ... A - Zero or One 模拟. #include <bits/stdc++.h> using namespace std; in ...

  7. ACM ICPC, JUST Collegiate Programming Contest (2018) Solution

    A:Zero Array 题意:两种操作, 1 p v  将第p个位置的值改成v  2  查询最少的操作数使得所有数都变为0  操作为可以从原序列中选一个非0的数使得所有非0的数减去它,并且所有数不能 ...

  8. ACM ICPC, Amman Collegiate Programming Contest (2018) Solution

    Solution A:Careful Thief 题意:给出n个区间,每个区间的每个位置的权值都是v,然后找长度为k的区间,使得这个区间的所有位置的权值加起来最大,输出最大权值, 所有区间不重叠 思路 ...

  9. Codeforces Gym101473 A.Zero or One (2013-2014 ACM-ICPC Brazil Subregional Programming Contest)

    代码: #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #i ...

  10. Codeforces Gym101473 F.Triangles-前缀和 (2013-2014 ACM-ICPC Brazil Subregional Programming Contest)

    前缀和. 代码: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include< ...

随机推荐

  1. 《linux实用指令积累》持续更新。。。

    一.远程服务器文件拷贝 1.1.scp scp /home/a.txt root@127.0.0.1:/home/ 1.2.sshpass(适用于脚本调用,直接指定密码) 1.2.1.安装sshpas ...

  2. SPiT:超像素驱动的非规则ViT标记化,实现更真实的图像理解 | ECCV 2024

    Vision Transformer(ViT) 架构传统上采用基于网格的方法进行标记化,而不考虑图像的语义内容.论文提出了一种模块化的超像素非规则标记化策略,该策略将标记化和特征提取解耦,与当前将两者 ...

  3. SoftCLT: 时间序列的软对比学习《Soft Contrastive Learning for Time Series》(时间序列、时序分类任务、软对比学习、实例上软赋值距离差异、数据空间非嵌入空间度量相似性)

    2024年6月25日,10:11,好几天没看论文了,一直在摸鱼写代码(虽然也没学会多少),今天看一篇师兄推荐的. 论文:Soft Contrastive Learning for Time Serie ...

  4. Go日志管理库zap

    一.zap介绍 在许多Go语言项目中,我们需要一个好的日志记录器能够提供下面这些功能: 1.能够将事件记录到文件中,而不是应用程序控制台. 2.日志切割-能够根据文件大小.时间或间隔等来切割日志文件. ...

  5. CSS – Design System

    介绍 这篇 Tailwind CSS 的教程:Translating a Custom Design System to Tailwind CSS 充分的体现了什么是 Design System. 设 ...

  6. 参与 2023 第二季度官方 Flutter 开发者调查

    Flutter 3.10 已经正式发布,每个季度一次的 Flutter 开发者调查也来啦!邀请社区的各位成员们填写: 调研旨在了解你对 Flutter 的满意程度以及对其各个子系统的反馈.你的意见将对 ...

  7. JavaScript中if嵌套assert的方法

    在JavaScript中,通常我们不会直接使用assert这个词,因为JavaScript标准库中并没有直接提供assert函数(尽管在一些测试框架如Jest.Mocha中经常看到).但是,我们可以模 ...

  8. MMU和SMMU IOMMU使用场景和区别,SMMU技术与cache

    1.各种MMU MMU是memory manage unit 内存管理单元: SMMU是system memory manage unit 系统内存管理单元: IOMMU和SMMU的功能基本相同,只是 ...

  9. 22. uni-app 怎么跳转界面

    methods: { //gonavigate()为点击响应事件,可在HTML部分设置 @tap="gonavigate()" gonavigate(){ uni.navigate ...

  10. SQL注入利用及绕过总结

    SQL注入及绕过姿势总结 概述 SQL注入指用户输入的参数可控且没有被过滤,攻击者输入的恶意代码被传到后端与SQL语句一起构造并在数据库中执行 不同数据库的语法可能存在差异,以MySQL为例,其他差异 ...