首页
关于
Search
1
Codeforces Round 930 (Div. 2)
15 阅读
2
测试页面
11 阅读
3
Codeforces Round 931 (Div. 2)
11 阅读
4
Codeforces Round 926 (Div. 2)
10 阅读
5
Codeforces Round 922 (Div. 2)
7 阅读
默认分类
codeforces
实战题解
登录
Search
算法小何
累计撰写
88
篇文章
累计收到
22
条评论
首页
栏目
默认分类
codeforces
实战题解
页面
关于
搜索到
88
篇与
的结果
2024-08-26
Codeforces Round 861 (Div. 2)
Petya, Petya, Petr, and Palindromes算法本质思维题目大意给定长度n的数组。定义某个奇长度数组的成本:以回文对不相等的对数输出所有长度k的子数组的成本之和。n k <= 2e5思路推演稍加模拟即可发现,数组奇偶下标可以分开看。为了避免重复,我们仅遍历左端点,通常来说,右端点是右侧k/2个元素(奇偶分开处理后)。但是首尾有所不同。一种方法是单独处理首尾附近的点。这其实就是模拟写法,推理写仔细点即可。还有一种方法是整体看待。对于每个左端点来说,其右端点是一个区间值。且题目要求保证与相同值关系很大。我们可以用一个vector来存放相同值的下标,然后方便计算期间。这个做法的难点在于计算区间的公式较难推理。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 void solve() { cin>>n>>k; vector<vector<int>> cod0(2e5+5), cod1(2e5+5); // 奇偶分开讨论,记录每个值的下标 vector<int> a(2e5+5); for (int i=1; i<=n; i++) { vector<vector<int>> &v = (i%2 ? cod1 : cod0); int x=in(); a[i] = x; v[x].push_back(i); } int ans=0; for (int i=1; i<=n; i++) // 枚举a[i]为左端点 { vector<vector<int>> &v = (i%2 ? cod1 : cod0); int x=a[i]; int l = max(i, i+k-1-2*(i-1)); // l~r的范围是右端点的区间(a[]中的下标),这里的公式是重点 int r = min(i+k-1, i+2*(n-i - k/2)); if (r<l) continue; int sum = (r-l)/2 + 1; // sum表示l~r区间值的数目,num表示这其中值为x的数目 int num = upper_bound(v[x].begin(), v[x].end(), r) - lower_bound(v[x].begin(), v[x].end(), l); ans += sum-num; } cout<<ans<<endl; return; }Minibuses on Venus (easy version)算法本质思维、想象力题目大意给定n k mod,定义长度n的数组a[]美丽:所有元素值范围[0~k-1]存在i使得$a_i ≡ \sum_{j=1}^na_j(\mod k)$输出长度n美丽数组个数。n <= 100 k <= 30思路推演中等版本是需要数学板子优化如此小的数据,实际上是对想象力的考验。显然是dp,思考状态,重点在于如何不重复。经过观察可发现,每个元素值v只对应一个和值sum,但是sum可能对应0~2个元素值v。所以整体思路应该是枚举sum值,然后判断其是否有对应的元素值。这里有两个朴素的想法:先计算和为sum值的所有方案数,再计算和为sum且没有使用对应元素值的方案数,两者相减即可如果有对应相同sum值,则称这两个元素值为一组。设计dp[i][s1][s2][0/1]:i表示下标,s1表示当前的和值,s2表示当前方案能否使得s2为合法和值。最后统计dp[n][s][s][1]的方案数即可。笔者使用的是方法2,但是写崩了,一直没改回来,看cup收到启发写了方法1,更简洁简单。代码写的是方法1,简单好理解。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 inline void solve() { cin>>n>>k>>mod; vector<vector<int>> dp(n+5, vector<int> (k+5)); // dp[x][y]=t表示1~x位总和位y的方案数有t dp[0][0] = 1; for (int i=1; i<=n; i++) { for (int v=0; v<k; v++) { for (int last=0; last<k; last++) dp[i][(v+last)%k] += dp[i-1][last], dp[i][(v+last)%k]%=mod; } } int ans=0; for (int sum=0; sum<k; sum++) { vector<vector<int>> dp2(n+5, vector<int> (k+5)); // dp2[x][y]=t同上,但是不能使用sum对应的值 dp2[0][0] = 1; int v1=-1, v2=-1; // 计算sum对应的两个值 if (sum%2==0) v1=sum/2; if ((sum+k)%2==0) v2=(sum+k)/2; for (int i=1; i<=n; i++) { for (int v=0; v<k; v++) { if (v==v1 || v==v2) continue; for (int last=0; last<k; last++) dp2[i][(v+last)%k] += dp2[i-1][last], dp2[i][(v+last)%k]%=mod; } } ans += dp[n][sum] - dp2[n][sum]; ans = (ans%mod + mod) % mod; } cout<<ans<<endl; return; }title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。
2024年08月26日
0 阅读
0 评论
0 点赞
2024-08-26
Codeforces Round 857 (Div. 2)
Buying gifts算法本质思维、STL应用题目大意(抽象)给定n张卡牌,每张有黑白两面,每一面都有数值。玩家可以选择让卡牌某面朝上。输出最小化的| max(黑色面数值) - max(黑色面数值) |。思路推演这种题相当简单。因为是最大值,所以我们可以枚举黑色面选取的最大值x。除了当前这卡牌,黑面值>x的卡牌必须选择白面,黑面值<=x的卡牌都可以任意选择黑白面。在这个情况下,凑一个白面最大值使得其与x最近即可。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 inline void solve() { cin>>n; vector<pair<int,int>> v; multiset<int> st1, st2; for (int i=0; i<n; i++) v.push_back({in(), in()}); sort(v.begin(), v.end()); for (int i=0; i<n; i++) st2.insert(v[i].second); int ans = 1e9; for (int i=0; i<n; i++) { st2.erase(st2.find(v[i].second)); int res=1e9, x=v[i].first, top=-1; // top是必须白面卡牌中的最大值 if (st2.size()) // st2是必选的部分 { top = *st2.rbegin(); res = abs(top-x); } auto it = st1.lower_bound(x); // st1是可选的部分 if (it!=st1.end() && *it>=top) // 可选部分找离x最近的,同时需要>=top才能生效 res = min(res, abs(*it - x)); if (it!=st1.begin() && *prev(it)>=top) res=min(res, abs(*prev(it)-x)); ans = min(ans, res); st1.insert(v[i].second); } cout<<ans<<endl; return; }Music Festiva算法本质思维题目大意给定若干个不同长度数组,现在玩家需要排列数组的顺序(数组内部元素顺序不会改变),组成一个数组a[]。定义数组的美丽值:若某个元素比其之前的所有元素都大,则+1美丽值(首元素必+1)输出a[]的最大美丽值。元素个数、数组个数、总元素个数、元素大小 <= 2e5思路推演稍加模拟即可发现,每个数组的其实仅需保留>数组之前所有元素的元素。比如[2, 1, 3, 3, 1]就可以简化成[2, 3]这其实变成了一个区间问题,显然我们应该优先处理那些靠前的区间,但是此题中,区间的质量分布并非均匀的,而是随机侧重的。这让贪心很难解决,于是开始思考dp能否搞定。思考区间的含义,区间l r来说,其值可以由<r的所有可能转移而来,这就是dp。构建dp[x]=t表示可选最大值x时美丽值最大是t。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 inline void solve() { cin>>n; map<int, vector<int>> cod, mp; // cod[x]表示第x个数组的形态(简化后),mp[x]表示以x为右端点的区间的id vector<int> alive; // 离散化,记录关键点(这点有点毛病,纯粹没有招硬加离散化加点难度) for (int i=0; i<n; i++) { cin>>m; vector<int> v; while (m--) { int x=in(); if (v.size()==0 || x>v.back()) v.push_back(x), alive.push_back(x); } mp[v.back()].push_back(i); cod[i] = v; } alive.push_back(0); // 手动添加一个0,可以省去一些边界检查的代码 sort(alive.begin(), alive.end()); alive.erase(unique(alive.begin(), alive.end()), alive.end()); // 排序去重 vector<int> dp(alive.size()); // dp[x]=t选完元素后的最大是x时美丽值为t for (int i=0; i<dp.size(); i++) { if (i>0) dp[i] = max(dp[i], dp[i-1]); // 直接继承 int val = alive[i]; for (int id:mp[val]) { vector<int> &v = cod[id]; int cnt=v.size(); for (int x:v) { int p=lower_bound(alive.begin(), alive.end(), x) - alive.begin(); dp[i] = max(dp[i], dp[p-1] + cnt); // dp转移公式 cnt--; } } } int ans = dp.back(); cout<<ans<<endl; return; }title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。
2024年08月26日
0 阅读
0 评论
0 点赞
2024-08-26
Codeforces Round 850 (Div. 2)
Letter Exchange算法本质模拟、思维题目大意有m个人,每个人随机得到3个字符,保证这3m个字符中有m个a、m个b、m个c。现在若某个人有3个不同字符则会开心。定义交换操作:选择某两个人,每个人给出一个字符、收到对方给的字符输出全部人开心的最少次数、操作信息。思路推演恶心的模拟题朴素的想法就是,可以将人分成10类,然后讨论他们的关系即可。稍加模拟可以发现,其实只与他们的需求有关,比如aab可以视作存在一个需求:出a收b。稍加推理可以发现,每次交换最好的结果是满足2个需求,至少是满足一个需求、转换另一个需求。一共有6种需求,可以分成3组需求,每组内部先相互交换。随即会发现,每组需求剩余的数目一致,且一定构成环,类似于样例2的例子。模仿样例2的做法处理即可。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 inline void solve() { cin>>n; string xxx="inw"; map<pair<char,char>, vector<int>> mp; // {c1, c2},出c1收c2 for (int i=1; i<=n; i++) { string s; cin>>s; map<char, int> cod; for (auto c:s) cod[c]++; char topc; // 找到需要出的字符 for (auto c:xxx) if (cod[c]>1) topc = c; for (auto c:xxx) if (cod[c]==0) mp[{topc, c}].push_back(i); } vector<pair<int,int>>id; // 记录每次操作的id vector<pair<char,char>>zifu; // 记录每次操作的字符 for (int i=0; i<3; i++) { for (int j=i+1; j<3; j++) { char c1=xxx[i], c2=xxx[j]; while (mp[{c1, c2}].size() && mp[{c2, c1}].size()) { vector<int> &v1=mp[{c1, c2}], &v2=mp[{c2, c1}]; id.push_back({v1.back(), v2.back()}); zifu.push_back({c1, c2}); v1.pop_back(); v2.pop_back(); } } } vector<int> v1, v2, v3; char c1, c2, c3; if (mp[{'i', 'n'}].size()) c1='i', c2='n', c3='w'; else c1='n', c2='i', c3='w'; v1 = mp[{c1, c2}]; v2 = mp[{c2, c3}]; v3 = mp[{c3, c1}]; m = v1.size(); while (m--) { int d1=v1.back(), d2=v2.back(), d3=v3.back(); id.push_back({d1, d2}); zifu.push_back({c1, c2}); id.push_back({d2, d3}); zifu.push_back({c1, c3}); v1.pop_back(); v2.pop_back(); v3.pop_back(); } cout<<id.size()<<endl; for (int i=0; i<id.size(); i++) cout<<id[i].first<<" "<<zifu[i].first<<" "<<id[i].second<<" "<<zifu[i].second<<endl; return; }Monsters (hard version)算法本质思维、数据结构题目大意给定长度n的数组a[],表示第i只怪物的血量。现在玩家有2个技能:基础技能:消耗一点能量,使得某个怪物生命值-1必杀技:仅能主动释放一次,不消耗能量,使得所有怪物生命值-1,若杀死某个怪物则会被动再释放一次(可无限叠加)easy版本:干掉所有怪物,输出玩家最小化的能量消耗。hard版本:遍历r ~ [1~n],仅存在1~r的怪物,输出玩家最小化的能量消耗。思路推演这里只推理hard版本思路是希望必杀技消耗的生命值最大,显然把必杀技留在最后时刻用收益最大。比如[2, 3, 5, 5, 9]就应该先处理成[1, 2, 3, 4, 5]。朴素的想法是,要构建一个结构,使得每次加入新的怪物,可以log级别处理。初始的想法是链接,记录变成1的元素原来的值、变成2的元素原来的值等等,这里大概思考了10来分钟,一直没有想到可以log级别维护的做法。在上面思考的过程也发现了一个事,新增值是否变化后数组的最大值,这个指标比较关键。稍加研究可以发现,比如[1, 4, 4, 4, 4]这个数组,理想情况其最好变成[1,2,3,4,5],但<=4的元素个数为5,这说明其中<=4的元素必然有某个值重复了。同时检查<=1 <=2 <=3的元素个数,可以确定这个重复的值为4,最后一定会变成[1,2,3,4,4]。这给了启发,可以称某个4值为多余的数。如果能排除多余数的干扰,则最后必然剩下一个有规律的数组,计算会十分方便。当加入一个新元素,如何判断是否迫使某个元素多余且找到这个元素。据上面可知,判断多余元素通过前缀个数 > 当前值判断的。这里我们可以建立一个线段树Bit[x]=t表示x - 当前初始数组中<=x的元素个数。这样当Bit[x]值为负的时候,就表明出现了多余的数。(注:同时出现多个负值,多余的数应该是x值最小的那个)多余的数我们特定处理即可。ac核心代码线段树要求:区间加减找最小值的id(同样最小找最左端的)因为不会写这个线段树,让焦写的,用他账号提交的,过了。头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。
2024年08月26日
0 阅读
0 评论
0 点赞
2024-08-26
Codeforces Round 813 (Div. 2)
Empty Graph算法本质思维题目大意存在n个点,给定一个数组a[]用于表示任意两点的距离:$dis_{u-v} = \min_{i=u}^v{a_i}$定义美丽值:最大的某对点距离现在玩家有k次操作机会,每次操作可以改变某个元素的值(范围[0~1e9])。输出操作后最大化的美丽值。思路推演稍加模拟可以发现,令bot为a[]的最小值,则美丽值 <= 2*bot。在这个限制之下,可以发现最大距离一定出自某两个相邻的点。这时就可以发现,如果我们用k-2个操作去改善最小值,剩余2个操作用于改善某对相邻点,这是一个相对不错的解法。这时就可以发现,本质上,操作可以分成2种:改善最小值改善相邻值改善相邻值至多需要2个操作,所以我们仅需枚举改善相邻值的操作:2、1、0即可。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 inline void solve() { cin>>n>>k; vector<int> a(n+5); set<vector<int>> st; // {值,id} for (int i=1; i<=n; i++) cin>>a[i], st.insert({a[i], i}); auto f = [&] { // 找到最小值id,赋值1e9 改善最小值的函数 int id = (*st.begin())[1]; // 最小值id st.erase({a[id], id}); a[id] = 1e9; st.insert({a[id], id}); k--; }; while (k>2) // k>2时,操作都用于改善最小值 f(); int ans = 0; if (k==2) { ans = max(ans, (*st.begin())[0] * 2); // 剩余2个操作可以改善相邻值,所以可以直接用最小值*2 f(); } if (k==1) { int bot = (*st.begin())[0]; // 最小值 for (int i=1; i<n; i++) { int res = max(a[i], a[i+1]); // 因为还剩余1个操作,所以可以取大值 res = min(res, bot*2); // 上限是bot*2 ans = max(ans, res); } f(); } if (k==0) { int bot = (*st.begin())[0]; // 最小值 for (int i=1; i<n; i++) { int res = min(a[i], a[i+1]); // 没有操作了,所以得取小值 res = min(res, bot*2); // 上限是bot*2 ans = max(ans, res); } } ans = min(ans, (int)1e9); // 之前没有限制ans的最小值,这里需要限制 cout<<ans<<endl; return; }LCM Sum (easy version)LCM Sum (hard version)算法本质思维题目大意对于区间[l~r],计数满足下列条件的三元组(a,b,c)个数:a < b < clcm(a, b, c) >= a+b+c简单版仅有5个区间,困难版有2e5个区间。l r <= 2e5思路推演稍加模拟可以发现,通常lcm(a,b,c)是远远大于a+b+c的,所以反向思考其小于的情况:lcm(a,b,c) == clcm(a,b,c) == 2c其中枚举lcm(a,b,c)==c的情况相对简单,我们仅需要知道c的合法范围的因数个数即可,简单版本可以直接暴力枚举。困难版本需要一些优化技巧,大概思索可以用二分优化,先不细究,思考第二种情况。lcm(a,b,c)==2c的情况稍显复杂,为了保证最后是2c,则必须a和b至少有一个元素提供足够多的2的指数。笔者的思路大抵如此,接下来只需要分类讨论即可。但是cup思路更加优秀,所以后面使用cup的思路。但是cup的思路因为没有分情况讨论,所以会跑满,需要注意常数。分情况讨论不会跑满。但实际上,这两种情况联系紧密,可以一起讨论。规定a b必须是2c的因数即可,但是这个过程要注意:保证l <= a < b < c对于简单版本,这不成问题,仅需暴力检测即可。接下来思考困难版本如何处理。思考时先假设做离线处理,如果后续发现不需要可以撤去显然一个合适的做法就是将这些数据存在a或者c中,然后用bit求和即可。因为删除相对麻烦,在模拟的时候发现,还是离线比较好使。最后选择存在a中,然后从小遍历右端点即可。ac核心代码 - 优雅暴力注意这版本代码会T,优化一下BIT的常数就能过。头文件、宏定义、快读模板、常见变量、常见变量等略。 vector<int> factor[maxn]; vector<pair<int,int>> tol[maxn]; int top = 2e5; inline void solve() { cin>>n; vector<int> ans(n); BIT bit(top); for (int i=0; i<n; i++) { int l=in(), r=in(); tol[r].push_back({l,i}); } for (int r=1; r<=top; r++) { int c=r; vector<int> &v = factor[2*c]; for (int b:v) { if (b>=c) break; for (int a:v) { if (a>=b) break; if (c%a || c%b) bit.add(a, a, a+b+c > c*2); // lcm(a,b,c)==2c else bit.add(a, a, 1); // lcm(a,b,c)==c } } for (auto [l, id] : tol[r]) { int res = (r-l+1)*(r-l)*(r-l-1)/6 - bit.getsum(l, r); ans[id] = res; } } for (int x:ans) cout<<x<<endl; return; } inline void solve_init() { for (int i=1; i<=top; i++) for (int w=2; i*w<=top*2; w++) factor[i*w].push_back(i); return; }ac核心代码 - 分类讨论头文件、宏定义、快读模板、常见变量、常见变量等略。 vector<pair<int,int>> tor[maxn]; // {r值, id值} vector<int> cod[maxn], cod2[maxn]; inline void solve() { cin>>n; vector<int> ans(n); for (int i=0; i<n; i++) { int l, r; cin>>l>>r; tor[l].push_back({r, i}); } int top = 2e5; BIT bit(2e5); int cnt=0; for (int l=top; l>=1; l--) { for (int w=2; l*w<=top*2; w++) { if (w%2) cod2[l*w].push_back(l); // 说明l*b的所有2因子全部由i提供 else cod[l*w].push_back(l); // 考虑lcm(a,b,c) == c的情况 if (l*w<=top) { int c=l*w; int num = cod[c].size() + cod2[c].size(); bit.add(c, c, num-1); } // 考虑lcm(a,b,c) == 2c && a+b+c > 2c的情况 if (l*w%2==0) { int c=l*w/2; sort(cod2[2*c].begin(), cod2[2*c].end()); sort(cod[2*c].begin(), cod[2*c].end()); int a=l, b=c-a; // 当另一个数的选择>b时会无效 int res=0; if (w%2) { // 新增a值在cod[2c]的情况 res += cod[2*c].end() - upper_bound(cod[2*c].begin(), cod[2*c].end(), b) - 1; // 这里需要手动-1,因为cod[2c]必然有因数c,我们不能让b==c // 新增a值在cod2[2c]的情况 if (a < b) res += cod2[2*c].end() - upper_bound(cod2[2*c].begin(), cod2[2*c].end(), b); } else res += cod2[2*c].end() - upper_bound(cod2[2*c].begin(), cod2[2*c].end(), b); bit.add(c, c, res); } } for (auto [r, id]:tor[l]) { int len = r-l+1; int res = bit.getsum(l, r); ans[id] = len*(len-1)/2*(len-2)/3 - res; } } for (int x:ans) cout<<x<<endl; return; }title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。
2024年08月26日
1 阅读
0 评论
0 点赞
2024-08-26
Codeforces Round 810 (Div. 2)
Rain算法本质思维、数据结构题目大意(抽象)在一维数轴上,有n个大块从天而降,类似于俄罗斯方块,每个大块都是正直角三角形且长边平行数轴。现在假设第i个大块不存在,检查最后图形是否最高高度超过m。n <= 2e5 方块位置、高度 <= 1e9思路推演稍加推理即可发现,最高高度一定出现于某个三角形的位置。尝试直接求解发现困难重重,但是可以先求解出n个三角形的形状后尝试检查挪去是否可行。求出n个三角形之后的形状相对简单,朴素的根据位置从左向右贪心即可,但是写起来稍微有点复杂。这里介绍一个更巧妙的方法:要想n个三角形形状能够求解,必须一定程度上规则。玩家最后想要的是每个点的高度数组,这个数组的导数即每个点的斜率数组,继续求导即每个点的斜率加速度数组。可以发现,每个三角形,其实只改变3个点的斜率加速度,随后即可求得。接下来思考如果减少某个三角形,会导致什么样的结果。定义位置p[]、初始高度h[]、n个三角形后的高度v[]。如果挪走i,考虑j的变化,先假设i<j(这里是按位置排序的):第j个三角形高度会变成:$v_j - (h_i - (p_j - p_i))$最后希望这个值≤m:$v_j + p_j - m ≤ h_i + p_i$最后处理$v_j + p_j - m$的最大值即可左侧同理。这里注意有一个优化写法。本身朴素来讲,需要用二分检查第i个三角形覆盖的范围,然后分别考虑覆盖点和非覆盖的点。我们考虑处理最大值的时候,其实仅需要检查v[j] > m的情况,在v[j] > m的情况中,j点不受i点的影响时,v[j]+p[j]-m > h[i]+p[i]和v[j] > m具有同等效力,所以可以直接判断而不用分成覆盖点和不覆盖点的情况。ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 XOR Triangle算法本质思维、数位dp题目大意给定一个二进制上限值n,计数三元组(a, b, c),其a⊕b、a⊕c、b⊕c构成非退化三角形。思路推演显然,这是一个数位dp。由于上限的限制,必须人为设定一个最大值c。还需要解决的一个问题是,其游戏规则后的本质。设a'=b⊕c、b'=a⊕c、c'=a⊕b模拟+思考后可以发现,拆位来看:a b c都是0或1a' b' c'全0其他a' b' c'存在2个1而且这个部分是十分均匀的,其中a' b' c'存在2个1的情况有三种:0 1 1由(0 1 1)和(1 0 0)转移而来1 0 1由(1 0 1)和(0 1 0)转移而来1 1 0由(1 1 0)和(0 0 1)转移而来当a b c中的二进制位有以上三种情况,则这个三元组必然可行,然后开始吃屎。注意借鉴这个题:https://www.luogu.com.cn/problem/P8766ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。 title算法本质题目大意思路推演ac核心代码头文件、宏定义、快读模板、常见变量、常见变量等略。
2024年08月26日
0 阅读
0 评论
0 点赞
1
...
3
4
5
...
18