Codeforces Round 686 (Div. 3)

1|0A. Special Permutation


#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve() { int n;cin>>n; cout<<n<<' '; for(int i=1;i<n;++i)cout<<i<<' '; cout<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; // init(); while(T--){ solve(); } return 0; }

2|0B. Unique Bid Auction


#include <bits/stdc++.h> using namespace std; #define int long long using i32 = int32_t; using pii = pair<int, int>; using vi = vector<int>; const int inf = 1e18; void solve() { int n; cin >> n; map<int, int> cnt; for (int i = 1, x; i <= n; i++) { cin >> x; if (cnt[x] == 0) cnt[x] = i; else cnt[x] = -1; } for (auto [k, v]: cnt) { if (v == -1) continue; cout << v << "\n"; return; } cout << "-1\n"; return; } i32 main() { int TC; for (cin >> TC; TC; TC--) solve(); return 0; }

3|0C. Sequence Transformation


我们分别统计出相同的每一种数字的位置,然后枚举保留那些数字,这些数字会把序列分层若干段,统计一下非空段的数量即。

#include <bits/stdc++.h> using namespace std; #define int long long using i32 = int32_t; using pii = pair<int, int>; using vi = vector<int>; const int inf = 1e18; const int A = 2e5; void solve() { int n; cin >> n; int res = inf; map<int, vi> cnt; for (int i = 1, x; i <= n; i++) { cin >> x; if (cnt[x].empty()) cnt[x].push_back(0); cnt[x].push_back(i); } for (auto [k, v]: cnt) { int ans = 0; v.push_back(n + 1); for (int i = 1; i < v.size(); i++) ans += (v[i] - v[i - 1]) > 1; res = min(res, ans); } cout << res << "\n"; } i32 main() { int TC; for (cin >> TC; TC; TC--) solve(); return 0; }

4|0D. Number into Sequence


质因数分解一下,然后找到最高次项的因子,次方数就是k,然后把其他因子都乘到任意一个数字上就好。

#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve() { int n,m;cin>>n; m=n; int c=0,ma; for(int i=2,cnt;i*i<=n;++i){ if(n%i)continue; cnt=0; while(n%i==0)cnt++,n/=i; if(cnt>c)ma=i,c=cnt; } if(n>1) if(1>c)ma=n,c=1; for(int i=0;i<c-1;++i)m/=ma; cout<<c<<'\n'; for(int i=0;i<c-1;++i)cout<<ma<<' '; cout<<m<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; // init(); while(T--){ solve(); } return 0; }

5|0E. Number of Simple Paths


图是一个基环树,找到基环树上所有的点,然后把环上的边都删掉,这样就会形成若干个森林。

u是的点,统计出u的子树大小cnt[u]

然后现在分情况讨论,对于两个点x,y之间在基环树上有多少个简单路径。

  1. 两个点在一个子树内,在基环树上只有一个简单路径
  2. 两个点不在一个子树内,在基环树上只有两个简单路径

所以我们对于每一个环上的点来考虑,对于两个点都在子树则Ccnt[u]2,如果其中一个点在子树内,另一个点不在,则2cnt[x]×(ncnt[x]),对于这种情况,每对点会枚举两次,所以还要除以 2

#include<bits/stdc++.h> using namespace std; #define int long long using i32 = int32_t; using vi = vector<i32>; using vI = vector<int>; void solve() { i32 n; cin >> n; vector e(n + 1, vi()); vi inDeg(n + 1); for (int i = 0, u, v; i < n; ++i) { cin >> u >> v; inDeg[u]++, inDeg[v]++; e[u].push_back(v), e[v].push_back(u); } // 拓扑 vector<bool> visH(n + 1); queue<i32> q; for (i32 i = 1; i <= n; ++i) if (inDeg[i] == 1) q.push(i); for (i32 u; not q.empty();) { u = q.front(), q.pop(); visH[u] = true; for (auto v: e[u]) if (--inDeg[v] == 1)q.push(v); } int ans = 0; for (int i = 1, omg; i <= n; ++i) { if (visH[i])continue; // 不在环上 vector<bool> vis(n + 1); omg = 0; queue<i32> que; que.push(i); for (int u; not que.empty();) { u = que.front(), que.pop(), omg++; vis[u] = true; for (auto y: e[u]) { if (visH[y] == false or vis[y] == true) continue; que.push(y); } } ans += omg * (omg - 1ll) / 2ll + (n - omg) * omg; } cout << ans << '\n'; return; } i32 main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); i32 TC; for (cin >> TC; TC; TC--) solve(); return 0; }

6|0F. Array Partition


首先可以知道的是对于一个区间,如果确定了区间的一个端点,区间的最值是单调的。所以可以提前预处理出前缀后缀的最大值。然后枚举x,去二分y。在二分的过程中需要知道区间的的最小值,所以套一个ST表就好。

#include<bits/stdc++.h> using namespace std; #define int long long using i32 = int32_t; using vi = vector<int>; const int N = 2e5, logN = log2(N) + 1; vi log_2(N); void init() { log_2[0] = -1; for (int i = 1; i < N; i++) log_2[i] = log_2[i >> 1] + 1; return; } struct ST { vector<vi> f; ST(const vi &a) { f = vector(a.size(), vi(logN + 1)); for (int i = 1; i < a.size(); i++) f[i][0] = a[i]; for (int j = 1; j <= logN; j++) for (int i = 1; i + (1 << j) - 1 < a.size(); i++) f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]); } int query(int l, int r) { int s = log_2[r - l + 1]; return min(f[l][s], f[r - (1 << s) + 1][s]); } }; void solve() { int n; cin >> n; vi a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; vi pre(n + 1), suf(n + 2); for (int i = 1; i <= n; i++) pre[i] = max(pre[i - 1], a[i]); for (int i = n; i >= 1; i--) suf[i] = max(suf[i + 1], a[i]); ST s(a); for (int i = 1, l, r, mid; i <= n; i++) { l = i+1, r = n; for (int mid, val; l <= r;) { mid = (l + r) / 2, val = s.query(i + 1, mid); if (pre[i] == val and val == suf[mid + 1]) { cout << "YES\n" << i << " " << mid - i << " " << n - mid << "\n"; return; } else if (val > pre[i]) { l = mid + 1; } else if (val < pre[i]) { r = mid - 1; } else { if (val < suf[mid + 1]) l = mid + 1; else r = mid - 1; } } } cout << "NO\n"; return; } i32 main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); init(); int TC; for (cin >> TC; TC; TC--) solve(); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17856296.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示