首页 > 其他分享 >AtCoder Beginner Contest 386 补题

AtCoder Beginner Contest 386 补题

时间:2025-01-03 21:33:26浏览次数:1  
标签:AtCoder return val Contest ll num 补题 386

E - Maximize XOR

题目大意

给出 \(n\) 个数,要选 \(k\) 个使异或和最大。

\(n\leq 2\times10^5,k\leq n\)

\(C_n^k\leq10^6\)

思路

由于那个组合数的性质,发现应该是直接深搜就可以的。可是发现 T 了。发现如果 \(k\) 很大那么还是不好处理。但是发现搜 \(k\) 个数和搜 \(n-k\) 个数是一样的,只不过第二种得到的值要用 \(n\) 个数的总异或值再异或一次。然后又因为 \(C_n^k=C_n^{n-k}\) 所以时间复杂度就是 \(O(C_n^k)\)。

代码

// Problem: E -  Maximize XOR
// Contest: AtCoder - AtCoder Beginner Contest 386
// URL: https://atcoder.jp/contests/abc386/tasks/abc386_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=2e5+5;
ll n,k,a[MAXN];
ll ans,ma;

ll Val=0;
void dfs(ll x,ll num,ll val){
    if(num>k||x>n+1){
        return;
    }
    if(num==n-k){
        ans=max(ans,Val^val);
        return;
    }
    if(num==k){
        ans=max(ans,val);
        return;
    }
    dfs(x+1,num+1,val^a[x]);
    dfs(x+1,num,val);
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;++i){
	    cin>>a[i];
	    ma=max(ma,a[i]);
	    Val^=a[i];
	}
	dfs(1,0,0);
	cout<<ans<<endl;
	return 0;
}

F - Operate K

题目大意

判断字符串 \(s\) 是否可以在 \(k\) 个编辑距离内变成 \(t\)。

一个编辑距离指进行下列三个操作之一:

  1. 将 \(s_i\) 改为 \(c\)。
  2. 删除 \(s_i\)。
  3. 在 \(s_i\) 和 \(s_{i+1}\) 之间新增字符 \(c\)。

\(|s|,|t|\leq 5\times10^5,k\leq20\)

思路

首先对于编辑距离有朴素 \(O(|s|\cdot|t|)\) 动规。设 \(f_{i,j}\) 表示当前从 \(s_1\) 到 \(s_i\) 在最小位 \(f_{i,j}\) 个编辑距离内匹配到了 \(t_1\) 到 \(t_j\)。

所以对于 \(f_{i,j}\) 有三种更新方式:

  1. \(f_{i,j}\leftarrow f_{i-1,j}+1\) 表示在 \(s_{i-1}\) 后新添一个 \(t_j\) 的字符完成匹配。
  2. \(f_{i,j}\leftarrow f_{i,j-1}+1\) 表示删除 \(s_i\)。
  3. \(f_{i,j}\leftarrow f_{i-1,j-1}+[s_i\neq t_j]\) 表示如果一样就直接继承,否则将 \(s_i\leftarrow t_j\)。

三种操作取最小值即可。初始化显然有 \(f_{0,i}=f_{i,0}=i\)。

考虑优化。发现 \(k\) 很小,所以编辑距离很大的状态可以直接剪枝掉。所以对于每一个 \(i\),最极端的情况就是 \(j=i-k\) 或 \(j=i+k\) 了。即长度为 \(k+1\) 的区间。所以对于每一个 \(i\) 只转移 \(j\in[\max(1,i-k),\min(|t|,i+k)]\) 的区间即可。

时间复杂度 \(O(|s|k)\)

代码

// Problem: C - Operate 1
// Contest: AtCoder - AtCoder Beginner Contest 386
// URL: https://atcoder.jp/contests/abc386/tasks/abc386_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN = 5e5 + 5;
string s1, s2;
unordered_map<ll, ll> dp[MAXN];
ll gt(ll i, ll j) {
  if (dp[i].count(j)) {
    return dp[i][j];
  }
  return 1e9;
}
int main() {
  ll k;
  cin >> k;
  cin >> s1 >> s2;

  ll l1 = s1.size(), l2 = s2.size();
  s1 = " " + s1;
  s2 = " " + s2;
  if (abs(l2 - l1) > k) {
    cout << "No" << endl;
    return 0;
  }
  for (int i = 0; i <= k; ++i) {
    dp[i][0] = i;
  }
  for (int i = 0; i <= k; ++i) {
    dp[0][i] = i;
  }
  for (int i = 1; i <= l1; ++i) {
    for (int j = max(1ll, i - k); j <= min(l2, i + k); ++j) {
      dp[i][j] = min({gt(i - 1, j) + 1, gt(i, j - 1) + 1,
                      gt(i - 1, j - 1) + (s1[i] != s2[j])});
      // cout << i << " " << j << " " << dp[i][j] << " " << gt(i - 1, j) + 1 <<
      // " "<< gt(i, j - 1) + 1 << " " << gt(i - 1, j - 1)<< endl;
    }
  }
  cout << (dp[l1][l2] <= k ? "Yes" : "No") << endl;
  return 0;
}

标签:AtCoder,return,val,Contest,ll,num,补题,386
From: https://www.cnblogs.com/tanghg/p/18638069/contest-abc386

相关文章

  • 关于此题E - Maximize XOR(Atcoder ABC 386)搜索技巧的一些总结
    传送门题目要求n个数中选k个数异或起来最大,我们想到字典树中最大异或和这一经典问题,但是很明显字典树只能解决任选两个数的最大异或,而此题是任选k个,那我们走投无路只能考虑爆搜。首先可以很容易写出一个暴力的搜索:voiddfs1(longlongpos,longlongsum,longlongkk){i......
  • 题解:AT_abc386_d [ABC386D] Diagonal Separation
    分析题面,发现题目求的是是否存在一个白点被\((1,1)\)和任意一个黑点围成的矩形内。先将所有黑点按\(x\)坐标排序。枚举所有的白点。找到所有横坐标不比该白点横坐标小的所有黑点的纵坐标的最大值所属点。如果该点的纵坐标小于该白点的纵坐标:(蓝点代表题目中的白点,红点......
  • AtCoder Beginner Contest 386(补题)
    AtCoderBeginnerContest386C-Operate1https://atcoder.jp/contests/abc386/tasks/abc386_c思路简单的条件判断题代码#include<bits/stdc++.h>typedefstd::pair<int,int>pii;#defineINF0x3f3f3f3f#defineMOD998244353usingi64=longlong;cons......
  • atcoder ABC385 部分题解
    G-CountingBuildings简要题义一个排列的\(L(P)\)为\(\sum_{i=1}^n[premax(i)=P_i]\),即前缀最大值为自身的位置数,\(R(P)\)同理为后缀最大值。有多少个排列使得\(L(P)-R(P)=k\)题解假设\(n,k\)是同阶的。我们从\(n\)到\(1\)依次插入数,考虑朴素的DP:设\(f_{i,k......
  • AtCoder Beginner Contest 386 赛后总结
    赛时A-D。菜。A-C模拟即可。D先检查一下竖着的一列有没有出现:白黑或者黑白黑的情况。有的话一定不行。因为每个白点的右下角一定都得是白的,就相当于对下面的行数取后缀最小值,这个可以使用差分实现。点击查看代码#include<bits/stdc++.h>#definelllonglong#def......
  • [题解](更新中)AtCoder Beginner Contest 386(ABC386) A~E
    A-FullHouse2容易发现,答案为Yes\(\iff\)输入中恰好出现了\(2\)种不同的数,可以用set等数据结构来计算不同元素的个数。点击查看代码#include<bits/stdc++.h>usingnamespacestd;set<int>se;signedmain(){ for(inti=1,a;i<=4;i++){ cin>>a; se.insert(a); } c......
  • AtCoder DP Contest(刷题记录)
    A-Frog1题意:给定\(n\)个石头,第\(i\)个石头的高度为\(h_i\).现在要求小青蛙从\(1\)号石头跳到\(n\)号石头,每次小青蛙可以选择从\(i\)号石头跳到\(i+1\)或\(i+2\)号石头,代价是起跳点与落点的高度差的绝对值。询问你最小代价。解法:\(dp[i]\)表示小青蛙跳到第号石头时的最小代......
  • CF补题 981-Div.3
    CF补题981-Div.3-20241226Dashboard-CodeforcesRound981(Div.3)-CodeforcesA:题目大意:\(x\)从\(0\)开始,轮流将\(x\)前后移动\(i*2-1\),求最后移动出$-n,n$的$i$#include<iostream>#include<math.h>usingnamespacestd;intmain(){ intT; c......
  • AtCoder Regular Contests
    \[\begin{matrix}\color{#d9d9d9}\blacksquare\color{#D9C5B2}\blacksquare\color{#B2D9B2}\blacksquare\color{#B2ECEC}\blacksquare\color{#B2B2FF}\blacksquare\color{#ECECB2}\blacksquare\color{#FFD9B2}\blacksquare\color{#FFB2B2}\blacksqu......
  • Atcoder_cf17_final_j Tree MST
    这是我的第一道黑题!言归正传,题意是,给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x\),\(y\)之间的边长为\(w_x+w_y+dis_{x,y}\),其中\(dis_{x,y}\)表示\(x\)和\(y\)在树上的距离,求完全图的最小生成树。常规的求最小生成树的算法有\(kruskal\)、\(prim\)。但是这里这......