2021CCPC新疆省赛题解BDEFGHIJK

K. chino with c language

题意

memcpy()memcpy()memcpy()不会检查源地址范围与目标地址范围是否重叠,它只从左往右复制每个字节;memmove()memmove()memmove()会检查源地址范围与目标地址范围是否重叠,若发生重叠,它会通过特殊处理使得目的地址填充上与源地址相同的数据.设两函数调用都需要三个参数p1,p2,lp_1,p_2,lp1​,p2​,l,分别表示源地址、目的地址、要复制的字节数是.如对下标从111开始的字符串"abcdefg"调用memcpy(1,3,5)memcpy(1,3,5)memcpy(1,3,5)将得到"ababab",而调用memmove(1,3,5)memmove(1,3,5)memmove(1,3,5)将得到"ababcde".

给定长度为n(1≤n≤1e5)n\ \ (1\leq n\leq 1\mathrm{e}5)n  (1≤n≤1e5)的、只包含小写英文字母的字符串sss,给定参数p1,p2,l(1≤p1,p2,l≤n,1≤p1+l−1,p2+l−1≤n)p_1,p_2,l\ \ (1\leq p_1,p_2,l\leq n,1\leq p_1+l-1,p_2+l-1\leq n)p1​,p2​,l  (1≤p1​,p2​,l≤n,1≤p1​+l−1,p2​+l−1≤n),分别输出调用memcpy(p1,p2,l)memcpy(p_1,p_2,l)memcpy(p1​,p2​,l)和memmove(p1,p2,l)memmove(p_1,p_2,l)memmove(p1​,p2​,l)的结果.

代码 -> 2021CCPC新疆省赛-K(模拟)

const int MAXN = 1e5 + 5;
int n;
char s[MAXN], t[MAXN];void solve() {cin >> n >> s + 1;strcpy(t + 1, s + 1);int p1, p2, l; cin >> p1 >> p2 >> l;for (int i = 0; i < l; i++) t[p2 + i] = s[p1 + i];for (int i = 0; i < l; i++) s[p2 + i] = s[p1 + i];cout << s + 1 << endl << t + 1;
}int main() {solve();
}


J. do NOT a=2b

题意

称一个序列是坏的,如果其中存在两个元素a,bs.t.a=2ba,b\ s.t.\ a=2ba,b s.t. a=2b.给定一个长度为n(1≤n≤1e5)n\ \ (1\leq n\leq1\mathrm{e}5)n  (1≤n≤1e5)的序列a1,⋯,an(1≤ai≤1e6)a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}6)a1​,⋯,an​  (1≤ai​≤1e6),删除尽量少的元素使得它不是坏的,输出最少要删除的元素的个数.

思路

dp[a][0]dp[a][0]dp[a][0]表示不删除值为aaa的元素,dp[a][1]dp[a][1]dp[a][1]表示删除所有值为aaa的元素.设值为aaa的元素个数为cnt[a]cnt[a]cnt[a].

注意到aaa只能是偶数,状态转移方程:{a为奇数{dp[a][0]=0,因为a2不是一个整数dp[a][1]=cnt[a],即要删除所有值为a的元素a为偶数{dp[a][0]=dp[b][1],即不删a就要删除所有值为b=a2的元素dp[a][1]=min⁡{dp[b][0],dp[b][1]}+cnt[a],删除a后b可删可不删\begin{cases}a为奇数\begin{cases}dp[a][0]=0,因为\dfrac{a}{2}不是一个整数 \\ dp[a][1]=cnt[a],即要删除所有值为a的元素\end{cases} \\ a为偶数\begin{cases}dp[a][0]=dp[b][1],即不删a就要删除所有值为b=\dfrac{a}{2}的元素 \\ dp[a][1]=\min\{dp[b][0],dp[b][1]\}+cnt[a],删除a后b可删可不删\end{cases}\end{cases}⎩⎨⎧​a为奇数{dp[a][0]=0,因为2a​不是一个整数dp[a][1]=cnt[a],即要删除所有值为a的元素​a为偶数{dp[a][0]=dp[b][1],即不删a就要删除所有值为b=2a​的元素dp[a][1]=min{dp[b][0],dp[b][1]}+cnt[a],删除a后b可删可不删​​.

注意到每个dp[a]dp[a]dp[a]都包含了dp[b]dp[b]dp[b]的最优解,故只需对所有2a>1e62a>1\mathrm{e}62a>1e6的aaa统计答案即可.

代码 -> 2021CCPC新疆省赛-J(线性DP)

const int MAXN = 1e6 + 5;
int n;
map<int, int> cnt;  // cnt[b]表示值为b的元素个数
int dp[MAXN][2];  // dp[a][0]表示不删除值为b的元素,dp[a][1]表示删除所有值为b的元素void solve() {cin >> n;while (n--) {int a; cin >> a;cnt[a]++;}for (int a = 1; a <= 1e6; a++) {if (a & 1) {dp[a][0] = 0;  // b/2不是整数dp[a][1] = cnt[a];  // 删除所有值为b的元素}else {dp[a][0] = dp[a / 2][1];  // 不删a就要删除所有值为b=a/2的元素dp[a][1] = min(dp[a / 2][0], dp[a / 2][1]) + cnt[a];  // 删除a后b可删可不删}}int ans = 0;for (int a = 5e5 + 1; a <= 1e6; a++)  // 对所有2a>1e6的a统计答案ans += min(dp[a][0], dp[a][1]);cout << ans;
}int main() {solve();
}


E. is the order a rabbit ??

题意

兔子交易市场有规则:①市场只在上午和下午开放,每天的上午、下午的兔子交易价格可能不同;②每天至多只能买一只兔子,每只兔子只能买一次;③每天只能卖一只兔子.某人到该交易市场经营nnn天,设他有足够的钱可用于购买兔子,第一天前和最后一天后他都没有兔子,问他最多能赚多少钱.

第一行输入一个整数n(1≤n≤1e5)n\ \ (1\leq n\leq 1\mathrm{e}5)n  (1≤n≤1e5).接下来nnn行每行输入两个整数a,b(1≤a,b≤1e9)a,b\ \ (1\leq a,b\leq 1\mathrm{e}9)a,b  (1≤a,b≤1e9),分别表示该天上午和下午兔子的价格.

思路

从最后一天往前推,维护当前的最高价格maxpricemaxpricemaxprice.

设某天上午和下午的价格分别是u,vu,vu,v.

(1)若maxprice≥max⁡{u,v}maxprice\geq \max\{u,v\}maxprice≥max{u,v},则以当天的最低价格min⁡{u,v}\min\{u,v\}min{u,v}买入,以maxpricemaxpricemaxprice卖出,利润maxprice−min⁡{u,v}maxprice-\min\{u,v\}maxprice−min{u,v}.

(2)若maxprice<max⁡{u,v}maxprice<\max\{u,v\}maxprice<max{u,v}:

​ ①若u<vu<vu<v,则当天上午买入,下午卖出,利润v−uv-uv−u.

​ ②若u≥vu\geq vu≥v且maxprice>vmaxprice>vmaxprice>v,则以maxpricemaxpricemaxprice买入,当天下午卖出,利润maxprice−vmaxprice-vmaxprice−v.

代码 -> 2021CCPC新疆省赛-E(思维)

const int MAXN = 1e5 + 5;
int n;
pii prices[MAXN];void solve() {cin >> n;for (int i = 1; i <= n; i++) cin >> prices[i].first >> prices[i].second;int maxprice = 0;  // 当前的最高价格ll ans = 0;for (int i = n; i >= 1; i--) {auto [u, v] = prices[i];if (maxprice >= max(u, v)) ans += maxprice - min(u, v);else {if (u < v) ans += v - u;else if (maxprice > v) ans += maxprice - v;maxprice = max(u, v);  // 更新最高价格}}cout << ans;
}int main() {solve();
}


G. cocktail with snake

题意

某游戏界面可视为一个n×mn\times mn×m的网格.初始时玩家在点(1,1)(1,1)(1,1)处,先向右走到(n,1)(n,1)(n,1),再向上走到(n,2)(n,2)(n,2),再向左走到(1,2)(1,2)(1,2),再向上走到(1,3),⋯(1,3),\cdots(1,3),⋯,重复该过程直至走到终点.每一步玩家可按路线移动111个单位长度,求移动kkk步后到达的点与起点的Manhattan距离.

有t(1≤t≤1e4)t\ \ (1\leq t\leq 1\mathrm{e}4)t  (1≤t≤1e4)组测试数据.每组测试数据输入三个整数n,m,k(1≤n,m≤1e18,0≤k≤min⁡{nm−1,1e18})n,m,k\ \ (1\leq n,m\leq 1\mathrm{e}18,0\leq k\leq \min\{nm-1,1\mathrm{e}18\})n,m,k  (1≤n,m≤1e18,0≤k≤min{nm−1,1e18}).

思路

如上图,将(1,1)→(3,1)→(3,2)(1,1)\rightarrow(3,1)\rightarrow(3,2)(1,1)→(3,1)→(3,2)视为一段,将(3,2)→(1,2)→(1,3)(3,2)\rightarrow (1,2)\rightarrow(1,3)(3,2)→(1,2)→(1,3)视为一段.显然移动kkk步后在第k′=⌊kn⌋k'=\left\lfloor\dfrac{k}{n}\right\rfloork′=⌊nk​⌋段,且k′k'k′为奇数时向右走,为偶数时向左走.显然向上走的距离Δy=k′\Delta y=k'Δy=k′,Δx\Delta xΔx只需考察k%nk\% nk%n和行进方向即可.

代码 -> 2021CCPC新疆省赛-G(思维)

void solve() {ll n, m, k; cin >> n >> m >> k;ll r = k % n;k/=n;ll ans = k;  // Δyif (k & 1) ans += (n - r - 1);else ans += r;cout << ans << endl;
}int main() {CaseT  // 单测时注释掉该行solve();
}


I. chino with mates

题意

给定一个长度为n(1≤n≤1e5)n\ \ (1\leq n\leq 1\mathrm{e}5)n  (1≤n≤1e5)的序列a1,⋯,an(−1e9≤ai≤1e9)a_1,\cdots,a_n\ \ (-1\mathrm{e}9\leq a_i\leq 1\mathrm{e}9)a1​,⋯,an​  (−1e9≤ai​≤1e9)和一个长度为m(1≤m≤1e5)m\ \ (1\leq m\leq 1\mathrm{e}5)m  (1≤m≤1e5)的序列b1,⋯,bn(−1e9≤bi≤1e9)b_1,\cdots,b_n\ \ (-1\mathrm{e}9\leq b_i\leq 1\mathrm{e}9)b1​,⋯,bn​  (−1e9≤bi​≤1e9).称数对(ai,bj)(a_i,b_j)(ai​,bj​)是好的,如果aibj∈[l,r](1≤i≤n,1≤j≤m,−1e9≤l≤r≤1e9)a_ib_j\in[l,r]\ \ (1\leq i\leq n,1\leq j\leq m,-1\mathrm{e}9\leq l\leq r\leq 1\mathrm{e}9)ai​bj​∈[l,r]  (1≤i≤n,1≤j≤m,−1e9≤l≤r≤1e9).问有几个好的数对(a,b)(a,b)(a,b).

思路

先将b[]b[]b[]升序排列.对每个aia_iai​,若aibj∈[l,r]a_ib_j\in[l,r]ai​bj​∈[l,r],则bjb_jbj​在lai\dfrac{l}{a_i}ai​l​和rai\dfrac{r}{a_i}ai​r​之间.

令left=min⁡{lai,rai},right=max⁡{lai,rai}left=\min\left\{\dfrac{l}{a_i},\dfrac{r}{a_i}\right\},right=\max\left\{\dfrac{l}{a_i},\dfrac{r}{a_i}\right\}left=min{ai​l​,ai​r​},right=max{ai​l​,ai​r​},在b[]b[]b[]上二分出第一个≥left\geq left≥left的位置pos1pos_1pos1​和第一个>right>right>right的位置pos2pos_2pos2​,

​ 则aia_iai​对答案的贡献为pos2−pos1pos_2-pos_1pos2​−pos1​.

代码 -> 2021CCPC新疆省赛-I(思维)

void solve() {int n, m; cin >> n >> m;vi a(n), b(m);for (int i = 0; i < n; i++) cin >> a[i];for (int i = 0; i < m; i++) cin >> b[i];int l, r; cin >> l >> r;sort(all(b));ll ans = 0.;for (int i = 0; i < n; i++) {double left = (double)l / a[i], right = (double)r / a[i];if (cmp(left, right) > 0) swap(left, right);int pos1 = lower_bound(all(b), left) - b.begin();int pos2 = upper_bound(all(b), right) - b.begin();ans += pos2 - pos1;}cout << ans;
}int main() {solve();
}


F. chino with ball

题意

xxx轴上有编号1∼n1\sim n1∼n的nnn个球,其中第i(1≤i≤n)i\ \ (1\leq i\leq n)i  (1≤i≤n)个球的初位置坐标为pip_ipi​,初速度为viv_ivi​(以向右为xxx轴正方向).球的体积忽略不计,且两球碰撞时会交换速度.求kkk秒后每个球的位置.

第一行输入两个整数n,k(1≤n≤1e5,0≤k≤1e9)n,k\ \ (1\leq n\leq 1\mathrm{e}5,0\leq k\leq 1\mathrm{e}9)n,k  (1≤n≤1e5,0≤k≤1e9).接下来nnn行每行输入两个整数pi,vi(−1e9≤pi≤1e9,vi∈{−1,0,1})p_i,v_i\ \ (-1\mathrm{e}9\leq p_i\leq 1\mathrm{e}9,v_i\in\{-1,0,1\})pi​,vi​  (−1e9≤pi​≤1e9,vi​∈{−1,0,1}).数据保证所有球的初位置不同.

输出nnn个整数,其中第i(1≤i≤n)i\ \ (1\leq i\leq n)i  (1≤i≤n)个数表示编号为iii的球kkk秒后的位置.

思路

注意到两球交换速度可视为互相穿过了对方,故球kkk秒后的位置即pi+kvip_i+kv_ipi​+kvi​.但题目要求按原编号输出球kkk秒后的位置,互相穿过后继续向前的球未必是原来的球,可将所有初位置和末位置都升序排列,这时顺序一一对应.

代码 -> 2021CCPC新疆省赛-F(思维)

void solve() {int n, k; cin >> n >> k;vii start(n + 1);  // 初位置vi end(n + 1);  // 末位置for (int i = 1; i <= n; i++) {int p, v; cin >> p >> v;start[i] = { p,i };end[i] = p + k * v;}sort(start.begin() + 1, start.end());sort(end.begin() + 1, end.end());vi ans(n + 1);for (int i = 1; i <= n; i++) ans[start[i].second] = end[i];for (int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}int main() {solve();
}


B. cocktail with hearthstone

题意

某游戏的规则:①每个玩家的战绩用数对(a,b)(a,b)(a,b)表示,其中aaa表示胜利场数,bbb表示失败场数.初始时战绩为(0,0)(0,0)(0,0);②每轮胜利的玩家a++a++a++,失败的玩家b++b++b++,没有平局;③每轮对战的两个人的战绩相同,设为(a,b)(a,b)(a,b),则该轮结束后会产生一个(a+1,b)(a+1,b)(a+1,b)和一个(a,b+1)(a,b+1)(a,b+1);④若有玩家胜利nnn次或失败mmm次,他将自动退出游戏.

现安排了2n+m2^{n+m}2n+m个玩家,保证所有玩家在退出游戏前都能找到对手.现有qqq个询问,每个询问给定a,ba,ba,b,设战绩(a,b)(a,b)(a,b)符合退出游戏的要求,问有多少个人以战绩(a,b)(a,b)(a,b)退出游戏,答案对1e9+71\mathrm{e}9+71e9+7取模.

第一行输入三个整数n,m,q(1≤m<n≤2e5,1≤q≤2e5)n,m,q\ (1\leq m<n\leq 2\mathrm{e}5,1\leq q\leq 2\mathrm{e}5)n,m,q (1≤m<n≤2e5,1≤q≤2e5).接下来qqq行每行输入两个整数a,b(0≤a≤n,0≤b≤m)a,b\ \ (0\leq a\leq n,0\leq b\leq m)a,b  (0≤a≤n,0≤b≤m),数据保证a=na=na=n或b=mb=mb=m.

对每个询问,输出以战绩(a,b)(a,b)(a,b)退出游戏的人数,答案对1e9+71\mathrm{e}9+71e9+7取模.

思路

游戏过程:(0,0){(1,0){(2,0){(3,0)(2,1)(1,1){(2,1)(1,2)(0,1){(1,1){(2,1)(1,2)(0,2){(1,2)(0,3)(0,0)\begin{cases}(1,0)\begin{cases}(2,0)\begin{cases}(3,0) \\ (2, 1)\end{cases} \\ (1,1)\begin{cases}(2,1) \\ (1,2)\end{cases}\end{cases} \\ (0,1)\begin{cases}(1,1)\begin{cases}(2,1) \\ (1,2)\end{cases} \\ (0,2)\begin{cases}(1,2) \\ (0,3)\end{cases}\end{cases}\end{cases}(0,0)⎩⎨⎧​(1,0)⎩⎨⎧​(2,0){(3,0)(2,1)​(1,1){(2,1)(1,2)​​(0,1)⎩⎨⎧​(1,1){(2,1)(1,2)​(0,2){(1,2)(0,3)​​​.

第000层:(0,0)(0,0)(0,0)有111个.

第111层:(1,0)(1,0)(1,0)有111个、(0,1)(0,1)(0,1)有111个.

第222层:(2,0)(2,0)(2,0)有111个、(1,1)(1,1)(1,1)有222个、(0,2)(0,2)(0,2)有111个.

第333层:(3,0)(3,0)(3,0)有111个、(2,1)(2,1)(2,1)有333个、(1,2)(1,2)(1,2)有333个、(0,3)(0,3)(0,3)有111个.

显然个数的规律为杨辉三角.

考察a=na=na=n的情况.显然(a,b)(a,b)(a,b)在第(a+b)(a+b)(a+b)层,且在该层数量占比Ca+ba2a+b\dfrac{C_{a+b}^a}{2^{a+b}}2a+bCa+ba​​.但注意到a=na=na=n时,到达(a,b)(a,b)(a,b)前(a,b−1),(a,b−2),⋯(a,b-1),(a,b-2),\cdots(a,b−1),(a,b−2),⋯早已退出游戏,故能转移到(a,b)(a,b)(a,b)的合法状态只有(a−1,b)(a-1,b)(a−1,b),故占比应取Ca+b−1a−12a+b\dfrac{C_{a+b-1}^{a-1}}{2^{a+b}}2a+bCa+b−1a−1​​.总人数2n+m2^{n+m}2n+m,故ans=2n+m−a−b⋅Ca+b−1a−1ans=2^{n+m-a-b}\cdot C_{a+b-1}^{a-1}ans=2n+m−a−b⋅Ca+b−1a−1​.同理b=mb=mb=m时,ans=2n+m−a−b⋅Ca+b−1b−1ans=2^{n+m-a-b}\cdot C_{a+b-1}^{b-1}ans=2n+m−a−b⋅Ca+b−1b−1​.

注意特判(a,b)=(n,m)(a,b)=(n,m)(a,b)=(n,m)的情况,因无任何合法状态能转移到(n,m)(n,m)(n,m),故ans=0ans=0ans=0.

代码 -> 2021CCPC新疆省赛-B(组合计数)

const int MAXN = 4e5 + 5;
const int MOD = 1e9 + 7;
int fac[MAXN], ifac[MAXN];void init() {  // 预处理阶乘及其逆元fac[0] = 1;for (int i = 1; i < MAXN; i++) fac[i] = (ll)fac[i - 1] * i % MOD;ifac[MAXN - 1] = qpow(fac[MAXN - 1], MOD - 2, MOD);for (int i = MAXN - 1; i; i--) ifac[i - 1] = (ll)ifac[i] * i % MOD;
}int C(int n, int m) {  // 组合数C(n,m)return (ll)fac[n] * ifac[m] % MOD* ifac[n - m] % MOD;
}void solve() {init();int n, m; cin >> n >> m;CaseT{int a,b; cin >> a >> b;if (a == n && b == m) {cout << 0 << endl;continue;}int ans = 0;if (a == n) ans = qpow(2, n + m - a - b, MOD) * C(a + b - 1, a - 1) % MOD;else ans = qpow(2, n + m - a - b, MOD) * C(a + b - 1, b - 1) % MOD;cout << ans << endl;}
}int main() {solve();
}


H. cocktail with pony

题意

xxx轴的线段[1,n][1,n][1,n]上A在追B,其中A初位置为x1x_1x1​,每次走v1v_1v1​步;B初位置为x2x_2x2​,每次走v2v_2v2​步.B与A交替移动,B先移动,即B在奇数轮移动,A在偶数轮移动,且两人的移动都不能超出线段边界.若有某一瞬间A和B在同一位置,则A抓住B.B想尽量晚被抓住,A想尽快抓住B,两人都采取最优策略,问几轮后A能抓住B.

有t(1≤t≤1e4)t\ \ (1\leq t\leq 1\mathrm{e}4)t  (1≤t≤1e4)组测试数据.每组测试数据输入五个整数n,v1,v2,x1,x2(2≤n≤1000,1≤v1,v2≤1e9,1≤x1,x2≤n,x1≠x2)n,v_1,v_2,x1,x_2\ \ (2\leq n\leq 1000,1\leq v_1,v_2\leq 1\mathrm{e}9,1\leq x_1,x_2\leq n,x_1\neq x_2)n,v1​,v2​,x1,x2​  (2≤n≤1000,1≤v1​,v2​≤1e9,1≤x1​,x2​≤n,x1​=x2​).

思路

若初始时x1<x2x_1<x_2x1​<x2​,令x1=n−x1+1,x2=n−x2+1x_1=n-x_1+1,x_2=n-x_2+1x1​=n−x1​+1,x2​=n−x2​+1,统一为两人都往左走.

模拟.注意为保证B尽量晚被抓住,其位置应尽量靠左,则B移动到边界x=1x=1x=1处时若还有多余的步数会左右横跳,最终停在x=1x=1x=1或x=2x=2x=2处.

代码 -> 2021CCPC新疆省赛-H(思维+模拟)

void solve() {int n, v1, v2, x1, x2; cin >> n >> v1 >> v2 >> x1 >> x2;if (x1 < x2) x1 = n - x1 + 1, x2 = n - x2 + 1;  // 保证两人都往左走int ans = 1;while (true) {if (ans & 1) {  // B走if (x2 == 1 && x1 == 2) break;  // B的路被堵死if (x2 - v2 >= 1) x2 -= v2;  // B完整地向左走else if (v2 - x2 & 1) x2 = 1;  // B在边界附近左右横跳,最终停在x=1else x2 = 2;  // B在边界附近左右横跳,最终停在x=2}else {  // A走if (x1 - x2 <= v1) break;  // 下一步抓到x1 -= v1;  // A完整地向左走}ans++;}cout << ans << endl;
}int main() {CaseT  // 单测时注释掉该行solve();
}


D. cocktail with swap

题意

给定一个长度为nnn的字符串sss,下标从111开始.现有操作:选择下标i,j∈[1,n]s.t.l≤∣i−j∣≤ri,j\in[1,n]\ s.t.\ l\leq |i-j|\leq ri,j∈[1,n] s.t. l≤∣i−j∣≤r,交换sis_isi​和sjs_jsj​.求若干次(可能为零次)操作后能得到的字典序最小的字符串.

第一行输入三个整数n,l,r(2≤n≤1e5,1≤l≤r<n)n,l,r\ \ (2\leq n\leq 1\mathrm{e}5,1\leq l\leq r<n)n,l,r  (2≤n≤1e5,1≤l≤r<n).

思路I

①l=rl=rl=r时,只能跳着排序.

②l≤⌊n2⌋l\leq\left\lfloor\dfrac{n}{2}\right\rfloorl≤⌊2n​⌋时,显然能做到交换相邻元素,则能得到的字典序最小的字符串即原串升序排列的结果.

③l>⌊n2⌋l>\left\lfloor\dfrac{n}{2}\right\rfloorl>⌊2n​⌋时,分为两段[1,n−l],[l+1,n][1,n-l],[l+1,n][1,n−l],[l+1,n].

对情况①和③,预处理出所有能动的字符,对它们排序后放回原串即可.

代码I -> 2021CCPC新疆省赛-D(思维+模拟)

const int MAXN = 1e5 + 5;
char s[MAXN], tmp[MAXN];  // 原串、临时串void solve() {int n, l, r; cin >> n >> l >> r >> s;if (l == r) {for (int i = 0; i < l; i++) {// 预处理出能动的字符int m = 0, j = i;while (j < n) tmp[m++] = s[j], j += l;sort(tmp, tmp + m);// 结果放回原串m = 0, j = i;while (j < n) s[j] = tmp[m++], j += l;}}else if (l <= n / 2) sort(s, s + n);else {// 预处理出能动的字符int m = 0;for (int i = 0; i < n - l; i++) tmp[m++] = s[i];for (int i = l; i < n; i++) tmp[m++] = s[i];sort(tmp, tmp + m);// 结果放回原串m = 0;for (int i = 0; i < n - l; i++) s[i] = tmp[m++];for (int i = l; i < n; i++) s[i] = tmp[m++];}cout << s;
}int main() {solve();
}

思路II

用一个并查集dsu2dsu2dsu2维护每个起点开始的区间中能动的下标,枚举每个起点iii,将以其开始的区间中能动的下标jjj对应的集合合并.朴素做法时间复杂度O(n2)O(n^2)O(n2),会TLE.

考虑优化,注意到可用另一个并查集dsu1dsu1dsu1维护指针jjj下一步跳到的位置,保证每次jjj跳到下一段的开头,时间复杂度O(n)O(n)O(n).

代码II -> 2021CCPC新疆省赛-D(思维+并查集)

const int MAXN = 1e5 + 5;
int n, l, r;
string s;struct DSU {int n;  // 元素个数int fa[MAXN];  // fa[]数组int siz[MAXN];  // 集合大小void init() {  // 初始化fa[]、siz[]for (int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;}int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }bool merge(int x, int y) {  // 返回合并是否成功,即初始时是否不在同一集合中x = find(x), y = find(y);if (x != y) {if (siz[x] > siz[y]) swap(x, y);  // 保证x所在的集合小fa[x] = y;siz[y] += siz[x];return true;}else return false;}
}dsu1, dsu2;void solve() {cin >> n >> l >> r >> s;dsu1.n = n; dsu1.init();  // 维护维护j跳的位置dsu2.n = n; dsu2.init();  // 维护每个起点开始的区间中能动的下标vb vis(n);for (int i = 0; i < n; i++) {  // 枚举起点for (int j = i + l; j <= i + r && j < n; j = dsu1.find(j) + 1) {  // j跳到下一段的开头dsu2.fa[dsu2.find(j)] = dsu2.fa[dsu2.find(i)];vis[j] = true;if (vis[j - 1]) dsu1.fa[dsu1.find(j - 1)] = dsu1.fa[dsu1.find(j)];}}// 预处理每个起点开始的区间中出能动的字符的下标vector<vi> son(n);for (int i = 0; i < n; i++) son[dsu2.find(i)].push_back(i);for (int i = 0; i < n; i++) {if (son[i].size()) {// 预处理出能动的字符string t;for (auto j : son[i]) t.push_back(s[j]);sort(all(t));// 结果放回原串int idx = 0;for (auto j : son[i]) s[j] = t[idx++];}}cout << s;
}int main() {solve();
}


2021CCPC新疆省赛题解BDEFGHIJK相关推荐

  1. 2021CCPC江西省赛题解ABGHIJKL

    2021CCPC江西省赛题解ABGHIJKL K. Many Littles Make a Mickle 题意 有 t ( 1 ≤ t ≤ 100 ) t\ \ (1\leq t\leq 100) t ...

  2. 2021CCPC上海省赛题解ABCDEGHIJK

    2021CCPC上海省赛题解ABCDEGHIJK A. 小 A 的点面论 题意 给定两相异的非零向量(x1,y1,z1),(x2,y2,z2)(0≤xi,yi,zi≤10)(x_1,y_1,z_1), ...

  3. 2021ccpc女生赛 BCF题解

    2021ccpc女生赛 C (状压DP) 题意:给定一张图,每个节点隶属于一个公司,会有节点属于相同的公司,节点都有一个权值,问从节点1出发,到达第iii个点时能得到的最大价值是多少. 每个公司的红包 ...

  4. 校内训练赛题解第三篇

    校内训练赛题解 人气估值 解题思路 脑力训练计划 (模拟 + 字符串) 解题思路 大暑赛期(贪心 + 思维) 人气估值 题目描述 你是某动画制作公司的企划部长.如今动画制作公司制作的东西,已经不仅仅局 ...

  5. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛) 题解

    "科林明伦杯"哈尔滨理工大学第十届程序设计竞赛(同步赛) 题解 萌新又来写题解啦 原题链接 B 减成一 题意:存在n个数,每次操作可以任选一个区间使得区间内的所有数字减一.问最少多 ...

  6. 第一届『Citric杯』NOIP提高组模拟赛 题解

    [官方题解]第一届『Citric杯』NOIP提高组模拟赛 题解 第一题 柠檬超市 这题是本次模拟赛的送分题.做法显然. 但是注意此题有一个陷阱: 注意W和C的规模都是10^9,所以如果直接用doubl ...

  7. Comet OJ 2019 夏季欢乐赛题解

    Comet OJ 2019 夏季欢乐赛题解 我是来骗访问量的 A 完全k叉树 \(n\)个点的完全k叉树的直径. 直接做 B 距离产生美 直接做 C 烤面包片 \(n!!!\mod p\) 显然\(n ...

  8. 2021年 第十二届蓝桥杯第二期校内模拟赛题解(Java版)

    时隔多日,终于会写一些简单DP了哈哈哈! 稍微改版,方便阅读,若有错,请指出 2019年 第十届蓝桥杯省赛题解(JavaB组版) 2020年 第十一届蓝桥杯第一场省赛题解(JavaB组版) 2020年 ...

  9. 2022CCPC江苏省赛题解ACIJKL

    2022CCPC江苏省赛题解ACIJKL A. PENTA KILL! 题意 称一个人连续杀了五个不同的人为五杀.给定 n ( 1 ≤ n ≤ 1000 ) n\ \ (1\leq n\leq 100 ...

最新文章

  1. 二值网络--Structured Binary Neural Networks for Accurate Image Classification and Semantic Segmentation
  2. 节能无线信标Ver0:功率测试
  3. python 多个配置文件_django中如何如何针对不同的环境使用多个配置文件?
  4. eclipse 国际化 $NON-NLS-1$ 含义
  5. CentOS6.5安装python环境
  6. SpringMVC之安全性(一)
  7. Lesson 05 for Plotting in R for Biologists
  8. 配置zabbix当内存剩余不足10%的时候触发报警
  9. 适用于游戏开发领域的语言
  10. 一文学会如何做电商数据分析(附运营分析指标框架)
  11. Django开发Restful Api文档
  12. scrapy 引擎,调度器出入队列及去重原理及几个构造request方法
  13. element时间日期选择器组件设置默认时间
  14. React hooks中swr的原理和源码解析
  15. JPA以外键为条件查询出的List(外键过滤并存入JSONObject)
  16. Unity3D的Json篇:LitJson.dll插件
  17. man命令后带的数字含义
  18. SQL SERVER 数据库delete 未加where 条件数据误删恢复办法
  19. git提交忽略不必要的文件或文件夹
  20. 分享一个好用的串口调试助手

热门文章

  1. python计算当天零点时间
  2. 搜索下半场:微信要做大搜索吗?
  3. docker配置HTTP/HTTPS代理访问外网
  4. 模拟微信发送文件给好友/群
  5. envoy网络安全opa等
  6. linux系统下运行mysql占多大内存_linux 下mysql内存占用过高
  7. h5唤醒微信支付PHP,app内嵌微信h5支付,支付服务唤起支付处理
  8. APFS 强在哪里?
  9. 阿里技术专家:技术人员如何快速成长,实现职场跃迁?14页ppt干货分享
  10. 电影文件名缩写说明——DVDSCR,TS/TC,REMUX