P11234 [CSP-S 2024] 擂台游戏
今天zty带来的是 P11234 [CSP-S 2024] 擂台游戏 ,大家给个赞呗,zty放寒假的更新呢是会多起来的大概一天三四个吧,zty最近在冲榜大家多加支持先赞后看养成习惯先赞后看养成习惯。
前言
今天zty带来的是 P11234 [CSP-S 2024] 擂台游戏 ,大家给个赞呗,zty放寒假的更新呢是会多起来的大概一天三四个吧,zty最近在冲榜大家多加支持
先 赞 后 看 养 成 习 惯
先 赞 后 看 养 成 习 惯
演示用编译器及其标准
Dev C++ 6.7.5 Red panda C++14
正文
[CSP-S 2024] 擂台游戏
题目描述
小 S 想要举办一场擂台游戏,如果共有 2k2^k2k 名选手参加,那么游戏分为 kkk 轮进行:
- 第一轮编号为 1,21, 21,2 的选手进行一次对局,编号为 3,43, 43,4 的选手进行一次对局,以此类推,编号为 2k−1,2k2^k - 1, 2^k2k−1,2k 的选手进行一次对局。
- 第二轮在只保留第一轮的胜者的前提下,相邻的两位依次进行一场对局。
- 以此类推,第 k−1k - 1k−1 轮在只保留第 k−2k - 2k−2 轮的 444 位胜者的前提下,前两位、后两位分别进行对局,也就是所谓的半决赛。
- 第 kkk 轮即为半决赛两位胜者的决赛。
确定了游戏晋级的规则后,小 S 将比赛的规则设置为了擂台赛。具体而言,每位选手都有一个能力值 a1,a2,…,a2ka_1, a_2, \dots , a_{2^k}a1,a2,…,a2k,能力值为 [0,231−1][0,2^{31}-1][0,231−1] 之内的整数。对于每场比赛,会先抽签决定一个数 0/10/10/1,我们将第 RRR 轮的第 GGG 场比赛抽到的数记为 dR,Gd_{R,G}dR,G。抽到 000 则表示表示编号小的选手为擂主,抽到 111 则表示编号大的选手为擂主。擂主获胜当且仅当他的能力值 a≥Ra\geq Ra≥R。也就是说,游戏的胜负只取决于擂主的能力值与当前比赛是第几轮的大小关系,与另一位的能力值无关。
现在,小 S 先后陆续收到了 nnn 位选手的报名信息,他们分别告知了小 S 自己的能力值。小 S 会按照报名的先后顺序对选手进行编号为 1,2,…,n1, 2, \dots, n1,2,…,n。小 S 关心的是,补充尽量少的选手使总人数为 222 的整次幂,且所有选手进行一次完整的擂台游戏后,所有可能成为总冠军的选手的编号之和是多少。
形式化地,设 kkk 是最小的非负整数使得 2k≥n2^k\geq n2k≥n,那么应当补充 (2k−n)(2^k-n)(2k−n) 名选手,且补充的选手的能力值可以任取 [0,231−1][0,2^{31}-1][0,231−1] 之内的整数。如果补充的选手有可能取胜,也应当计入答案中。
当然小 S 觉得这个问题还是太简单了,所以他给了你 mmm 个询问 c1,c2,…,cmc_1,c_2,\dots,c_mc1,c2,…,cm。小 S 希望你帮忙对于每个 cic_ici 求出,在只收到前 cic_ici 位选手的报名信息时,这个问题的答案是多少。
输入格式
本题的测试点包含有多组测试数据。 但不同测试数据只是通过修改 a1,a2,…,ana_1, a_2, \dots , a_na1,a2,…,an 得到,其他内容均保持不变,请参考以下格式。其中 ⊕\oplus⊕ 代表异或运算符,a mod ba \bmod bamodb 代表 aaa 除以 bbb 的余数。
输入的第一行包含两个正整数 n,mn, mn,m,表示报名的选手数量和询问的数量。
输入的第二行包含 nnn 个非负整数 a1′,a2′,…,an′a'_1,a'_2,\dots,a'_na1′,a2′,…,an′,这列数将用来计算真正的能力值。
输入的第三行包含 mmm 个正整数 c1,c2,…,cmc_1, c_2, \dots , c_mc1,c2,…,cm,表示询问。
设 KKK 是使得 2K≥n2^K \geq n2K≥n 的最小的非负整数,接下来的 KKK 行当中,第 RRR 行包含 2K−R2^{K-R}2K−R 个数(无空格),其中第 GGG 个数表示第 RRR 轮的第 GGG 场比赛抽签得到的 dR,G=0/1d_{R,G}=0/1dR,G=0/1。
注意,由于询问只是将人数凑齐到 2k≥ci2^k\geq c_i2k≥ci,这里的 k≤Kk\leq Kk≤K,因此你未必会用到全部的输入值。
接下来一行包含一个正整数 TTT,表示有 TTT 组测试数据。
接下来共 TTT 行,每行描述一组数据,包含 444 个非负整数 X0,X1,X2,X3X_0,X_1,X_2,X_3X0,X1,X2,X3,该组数据的能力值 ai=ai′⊕Xi mod 4a_i=a'_i \oplus X_{i\bmod 4}ai=ai′⊕Ximod4,其中 1≤i≤n1\leq i\leq n1≤i≤n。
输出格式
共输出 TTT 行,对于每组数据,设 AiA_iAi 为第 iii(1≤i≤m1 \leq i \leq m1≤i≤m)组询问的答案,你只需要输出一行包含一个整数,表示 (1×A1)⊕(2×A2)⊕⋯⊕(m×Am)(1\times A_1) \oplus (2\times A_2) \oplus \dots \oplus (m\times A_m)(1×A1)⊕(2×A2)⊕⋯⊕(m×Am) 的结果。
样例 #1
样例输入 #1
5 5
0 0 0 0 0
5 4 1 2 3
1001
10
1
4
2 1 0 0
1 2 1 0
0 2 3 1
2 2 0 1
样例输出 #1
5
19
7
1
提示
【样例 1 解释】
共有 T=4T = 4T=4 组数据,这里只解释第一组。555 名选手的真实能力值为 [1,0,0,2,1][1, 0, 0, 2, 1][1,0,0,2,1]。555 组询问分别是对长度为 5,4,1,2,35, 4, 1, 2, 35,4,1,2,3 的前缀进行的。
- 对于长度为 111 的前缀,由于只有 111 号一个人,因此答案为 111。
- 对于长度为 222 的前缀,由于 222 个人已经是 222 的幂次,因此不需要进行扩充。根据抽签 d1,1=1d_{1,1} = 1d1,1=1 可知 222 号为擂主,由于 a2<1a_2 < 1a2<1,因此 111 号获胜,答案为 111。
- 对于长度为 333 的前缀,首先 111 号、222 号比赛是 111 号获胜(因为 d1,1=1d_{1,1} = 1d1,1=1,故 222 号为擂主,a2<1a_2 < 1a2<1),然后虽然 444 号能力值还不知道,但 333 号、444 号比赛一定是 444 号获胜(因为 d1,2=0d_{1,2} = 0d1,2=0,故 333 号为擂主,a3<1a_3 < 1a3<1),而决赛 111 号、444 号谁获胜都有可能(因为 d2,1=1d_{2,1} = 1d2,1=1,故 444 号为擂主,如果 a4<2a_4 < 2a4<2 则 111 号获胜,a4≥2a_4 \geq 2a4≥2 则 444 号获胜)。综上所述,答案为 1+4=51 + 4 = 51+4=5。
- 对于长度为 444 的前缀,我们根据上一条的分析得知,由于 a4≥2a_4 \geq 2a4≥2 ,所以决赛获胜的是 444 号。
- 对于长度为 555 的前缀,可以证明,可能获胜的选手包括 444 号、777 号、888 号,答案为 191919。
因此,该组测试数据的答案为 (1×19)⊕(2×4)⊕(3×1)⊕(4×1)⊕(5×5)=5(1 \times 19) \oplus (2 \times 4) \oplus (3 \times 1) \oplus (4 \times 1) \oplus (5 \times 5) = 5(1×19)⊕(2×4)⊕(3×1)⊕(4×1)⊕(5×5)=5。
【样例 2】
见选手目录下的 arena/arena2.in 与 arena/arena2.ans。
这组样例满足特殊性质 A。
【样例 3】
见选手目录下的 arena/arena3.in 与 arena/arena3.ans。
这组样例满足特殊性质 B。
【样例 4】
见选手目录下的 arena/arena4.in 与 arena/arena4.ans。
【样例 5】
见选手目录下的 arena/arena5.in 与 arena/arena5.ans。
【数据范围】
对于所有测试数据,保证:2≤n,m≤1052 \leq n, m \leq 10^52≤n,m≤105,0≤ai,Xj<2310 \leq a_i, X_j < 2^{31}0≤ai,Xj<231,1≤ci≤n1 \leq c_i \leq n1≤ci≤n,1≤T≤2561 \leq T \leq 2561≤T≤256。
测试点 | T=T=T= | n,m≤n,m\leqn,m≤ | 特殊性质 A | 特殊性质 B |
---|---|---|---|---|
1∼31\sim 31∼3 | 111 | 888 | 否 | 否 |
4,54,54,5 | 111 | 500500500 | 是 | 否 |
6∼86\sim 86∼8 | 111 | 500500500 | 否 | 是 |
9,109,109,10 | 111 | 500050005000 | 否 | 否 |
11,1211,1211,12 | 111 | 10510^5105 | 是 | 否 |
13∼1513\sim 1513∼15 | 111 | 10510^5105 | 否 | 是 |
16,1716,1716,17 | 444 | 10510^5105 | 否 | 否 |
18,1918,1918,19 | 161616 | 10510^5105 | 否 | 否 |
20,2120,2120,21 | 646464 | 10510^5105 | 否 | 否 |
22,2322,2322,23 | 128128128 | 10510^5105 | 否 | 否 |
24,2524,2524,25 | 256256256 | 10510^5105 | 否 | 否 |
特殊性质 A:保证询问的 cic_ici 均为 222 的幂次。
特殊性质 B:保证所有的 dR,G=0d_{R,G} = 0dR,G=0。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls x<<1
#define rs x<<1|1
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define ll long long
using namespace std;
const int N = (1 << 17) + 5;
int mx[20][N << 2], lg[N], aa[N], ok[N], a[N], c[N], n, m, nn = 1;
bool vis[N];
ll ans[N], sum;
struct node {
ll sum;
int x;
bool tp, d;
} t[N << 2];
inline void build(int x, int l, int r) {
if (l == r) {
t[x].x = l;
return ;
}
int mid = l + r >> 1, k = lg[r - l + 1], d = t[x].d;
build(lson);
build(rson);
int win = a[t[x << 1 | d].x] >= k;
t[x].x = t[x << 1 | (d ^ !win)].x;
if (!d && win)t[x].tp = 1, ok[r]++, ok[mid]--;
else t[x].tp = 0;
}
inline void build2(int x, int l, int r, int *mx) {
t[x].sum = (l + r) * (r - l + 1ll) / 2;
if (l == r)return ;
int mid = l + r >> 1, k = lg[r - l + 1], d = t[x].d;
if (~mx[x])mx[ls] = mx[rs] = mx[x];
else mx[x << 1 | d] = k;
build2(lson, mx);
build2(rson, mx);
}
inline void up(int x) {
sum += !vis[x] * x;
vis[x] = 1;
}
inline int rd() {
char c;
int f = 1;
while (!isdigit(c = getchar()))if (c == '-')f = -1;
int x = c - '0';
while (isdigit(c = getchar()))x = x * 10 + (c ^ 48);
return x * f;
}
inline char gc() {
char c;
while ((c = getchar()) <= ' ');
return c;
}
int main() {
// freopen("arena.in","r",stdin);
// freopen("arena.out","w",stdout);
n = rd();
m = rd();
for (int i = 1; i <= n; i++)aa[i] = rd();
for (int i = 1; i <= m; i++)c[i] = rd();
while (nn < n)nn <<= 1;
for (int i = 2; i <= nn; i++)lg[i] = lg[i >> 1] + 1;
for (int i = nn / 2; i; i >>= 1)
for (int j = i; j < i * 2; j++)
t[j].d = gc() - '0';
memset(mx, -1, sizeof mx);
for (int s = 0; (1 << s) <= nn; s++)
build2(1 << s, 1, nn>>s, mx[s]);
for (int T = rd(); T--;) {
int yh[4] = {rd(), rd(), rd(), rd()};
for (int i = 1; i <= n; i++)a[i] = aa[i] ^ yh[i & 3];
memset(ok, 0, sizeof ok);
build(1, 1, nn);
for (int i = nn, rt = 1, s = 0; i; i--) {
if ((1 << lg[i]) == i) {
if (i != nn)rt <<= 1, s++;
for (int j = 1; j <= i; j++)vis[j] = 0;
sum = 0;
up(t[rt].x);
}
ans[i] = sum;
if (ok[i] += ok[i + 1])continue;
up(i);
int x = i + nn - 1;
while (x != rt) {
int d = x & 1;
x >>= 1;
if (!d)
if (t[x].tp)sum += t[rs].sum;
else break;
else if (a[t[ls].x] >= mx[s][ls])up(t[ls].x);
}
}
ll num = 0;
for (int i = 1; i <= m; i++)num ^= i * ans[c[i]];
printf("%lld\n", num);
}
return 0;
}
后记
作者:zty郑桐羽呀
联系方式:(不挂了,有事私信)
兄弟们给个赞呗
先 赞 后 看 养 成 习 惯
更多推荐
所有评论(0)