CF2179 Round 1071 Div3 个人题解
个人题解
Nanami^2 Even in the rain.
2026年01月06日
预计阅读 5 分钟
1084 字
A
容易猜到答案就是
条件翻译一下就是 ,其中 。容易发现这种不等关系长度最多为 ,否则一定存在相等。所以当 时, 开头的不等关系一定完蛋。
B
枚举删掉哪一个就行,注意细节。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 2e5 + 5;int T, n, a[N];void solve() { cin >> n; int sum = 0; for(int i = 1;i <= n;i++) { cin >> a[i]; if(i != 1) sum += abs(a[i] - a[i - 1]); } int ans = sum, k = 0; a[n + 1] = 0; for(int i = 1;i <= n;i++) { int t = sum - (i != 1) * abs(a[i] - a[i-1]) - (i != n) * abs(a[i + 1] - a[i]) + (i != n && i != 1) * abs(a[i + 1] - a[i - 1]); ans = min(ans, t); } cout << ans << endl;}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> T; while(T--) solve(); return 0;}C
做出如下观察:
- 。取等时,显然要把所有数都变成 ,于是其它数自己模自己即可。
- 当取 时,这个 的值依然不变,于是我们需要把其它所有数都变成这个 。取模选的 自然是越大越好,对于一个非最小值的 ,最大的 是 ,于是乎我们对这些值取最小,就能得到最大的
注意后者求出的 可能小于 ,所以二者取较大就是答案。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = 2e5 + 5;int T, n, a[N];// 读错题了qwqvoid solve() { cin >> n; for(int i = 1;i <= n;i++) cin >> a[i]; sort(a + 1, a + n + 1); int ans = a[1]; int mn = 1e9; for(int i = 2;i <= n;i++) { mn = min(mn, a[i] - a[1]); } cout << max(mn, ans) << endl;}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> T; while(T--) solve(); return 0;}D
注意到和式的每一项单调不增,我们考虑让其每次减小都只减小 ,然后在贡献值不变的情况下,按照字典序贪心放进去即可。
那么第一个数一定是 。接下来一定会减少一个 ,为了最小化字典序,应当去掉最高位的 。以此类推,这个过程是 的。
设去掉最后一个 1 的结果为 ,从小到大把&上 popcount 不变的数扔进去,一定是字典序最小的方案。
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> PII;#define MP make_pair#define fi first#define se second#define pb push_back#define eb emplace_back#define SET(a,b) memset(a,b,sizeof(a))#define CPY(a,b) memcpy(a,b,sizeof(b))#define rep(i,j,k) for(int i=(j);i<=(k);++i)#define per(i,j,k) for(int i=(j);i>=(k);--i)int read() { int a=0, f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) a=a*10+c-'0', c=getchar(); return a*f;}const int N = (1 << 16) + 5;int T, n, a[N];bool v[N];vector<int> ans;void solve() { cin >> n; for(int i = 0;i < (1 << n);i++) { a[i] = i; v[i] = 0; } int U = (1 << n) - 1; ans.clear(); v[U] = 1; ans.pb(U); int x = U; for(int i = n - 1;i >= 0;i--) if(x & (1 << i)) { x -= (1 << i); ans.pb(x); v[x] = 1; for(int i = 0;i <= U;i++) if(!v[i]) { if(__builtin_popcount(x & i) != __builtin_popcount(x)) continue; ans.pb(i); v[i] = 1; } } for(int i = 0;i <= U;i++) if(!v[i]) ans.pb(i); for(auto x : ans) cout << x << " "; cout << endl;}signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> T; while(T--) solve(); return 0;}E
待补
F
待补
觉得这篇文章怎么样?
点个赞,让更多人看到!

评论区