标签:code turn 记录 += i+1 ati class 注意 end
A. k-Factorization
找出所有质因子,把多的合并一下
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
void solve(){
int n, k;
cin >> n >> k;
vector<int> vec;
for(int i = 2; i * i <= n; i++){
if(n%i!=0) continue;
while(n%i==0){
n /= i;
vec.push_back(i);
}
}
if(n!=1) vec.push_back(n);
if(k>vec.size()) cout << -1 << endl;
else{
while(vec.size() > k){
int x = vec.back();
vec.pop_back();
vec.back() *= x;
}
for(int x : vec) cout << x << ‘ ‘; cout << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
B. Odd sum
\(dp\)一下,\(dp[i][0]\)和\(dp[i][1]\)分别表示已经得到的子序列的和为偶数和奇数的情况的最大值
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n, A[MAXN], pre[MAXN];
int f[MAXN][2];
void solve(){
____();
cin >> n;
f[0][1] = -0x3f3f3f3f;
for(int i = 1; i <= n; i++){
int x; cin >> x;
if(x&1){
f[i][0] = max(f[i-1][0],f[i-1][1]+x);
f[i][1] = max(f[i-1][1],f[i-1][0]+x);
}else{
f[i][0] = max(f[i-1][0],f[i-1][0]+x);
f[i][1] = max(f[i-1][1],f[i-1][1]+x);
}
}
cout << f[n][1] << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
C. Minimal string
显然需要贪心选取最小的字母,这个用子序列自动机来做一下,同时维护一个栈,每次找到下一个最小的字母的位置,先和栈顶的字母比较,然后再把这个字母添加到答案里去,把中间中间跳过去的的字符全部加到栈里面去。
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
char s[MAXN];
int nxt[MAXN][26];
stack<char> stk;
void solve(){
cin >> s + 1;
int n = strlen(s+1);
for(int i = 0; i < 26; i++) nxt[n][i] = MAXN;
for(int i = n - 1; i >= 0; i--){
for(int j = 0; j < 26; j++) nxt[i][j] = nxt[i+1][j];
nxt[i][s[i+1]-‘a‘] = i+1;
}
string ret;
int ptr = 0;
while(true){
bool ok = false;
for(int i = 0; i < 26; i++){
if(nxt[ptr][i]!=MAXN){
while(!stk.empty() and stk.top()<=i+‘a‘) ret += stk.top(), stk.pop();
ret += s[nxt[ptr][i]];
for(int k = ptr + 1; k < nxt[ptr][i]; k++) stk.push(s[k]);
ok = true;
ptr = nxt[ptr][i];
break;
}
}
if(!ok) break;
}
while(!stk.empty()) ret += stk.top(), stk.pop();
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
D. Broken BST
从根到某个节点的路径是唯一的,所以我们可以知道从根到查询节点经过哪些点是需要走左儿子,哪些点需要走右儿子,显然走左儿子必须要满足查询节点的值比当前节点的值小,右儿子一定要查询节点的值比当前节点的值大,所以我们可以\(dfd\)过程中记录走左儿子的点的最小值和走右儿子的点的最大值,然后判断查询节点的值是否在可行区间内即可
注意处理值相同的情况
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int ls[MAXN], rs[MAXN], n, root, w[MAXN], ret;
bool vis[MAXN];
map<int,bool> msk;
void dfs(int u, int mi, int ma){
if(w[u]>=ma and w[u]<=mi) msk[w[u]] = true;
if(ls[u]!=-1) dfs(ls[u],min(mi,w[u]),ma);
if(rs[u]!=-1) dfs(rs[u],mi,max(ma,w[u]));
}
void solve(){
____();
cin >> n;
for(int i = 1; i <= n; i++){
cin >> w[i] >> ls[i] >> rs[i];
if(ls[i]!=-1) vis[ls[i]] = true;
if(rs[i]!=-1) vis[rs[i]] = true;
}
for(int i = 1; i <= n; i++) if(!vis[i]) root = i;
dfs(root,0x3f3f3f3f,-1);
for(int i = 1; i <= n; i++) if(!msk.count(w[i])) ret++;
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
E. Array Queries
如果暴力\(dp\)复杂度会很高,复杂度高的原因是会有很多小的\(k\),那么我们预处理出来所有小的\(k\)的答案就好了
设一个\(k\)上限,小于上限预处理,大于等于直接跑,选上限为\(\sqrt n\),复杂度为\(O(q\sqrt n)\)
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
const int lim = 300;
int n, A[MAXN], f[MAXN][lim];
void solve(){
____();
cin >> n;
for(int i = 1; i <= n; i++) cin >> A[i];
for(int k = 1; k < lim; k++){
for(int i = n; i >= 1; i--){
if(i+A[i]+k>n) f[i][k] = 1;
else f[i][k] = 1 + f[i+A[i]+k][k];
}
}
int q; cin >> q;
while(q--){
int p, k; cin >> p >> k;
if(k < lim) cout << f[p][k] << endl;
else{
int __count = 0;
while(p<=n) p = p+A[p]+k, __count++;
cout << __count << endl;
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
F.?Mice and Holes
显然需要把所有老鼠和洞按位置先排序
然后\(dp[i][j]\)表示考虑前\(i\)个洞口,安排了\(j\)只老鼠的最小距离和
那么转移方程就长这样:
其中\(S[i]\)表示前\(i\)个老鼠到当前枚举的洞口的距离和,\(c_i\)表示\(i\)号洞口的容量
由于转移方程中\(S[j]\)是定值,可以用单调队列来维护
// #pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 5007;
typedef long long int LL;
int n, m, x[MAXN];
LL f[2][MAXN], dis[MAXN];
pair<int,int> hole[MAXN];
pair<LL,int> que[MAXN];
void solve(){
____();
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> x[i];
for(int i = 1; i <= m; i++) cin >> hole[i].first >> hole[i].second;
sort(x+1,x+1+n); sort(hole+1,hole+1+m);
memset(f,0x3f,sizeof(f));
int tag = 1; f[0][0] = 0;
for(int i = 1; i <= m; i++, tag ^= 1){
memset(f[tag],0x3f,sizeof(f[tag]));
f[tag][0] = 0;
int d = hole[i].first, c = hole[i].second;
for(int j = 1; j <= n; j++) dis[j] = dis[j-1] + abs(d-x[j]);
int head = 0, tail = -1;
que[++tail] = {0,0};
for(int j = 1; j <= n; j++){
LL dp = f[tag^1][j] - dis[j];
while(head<=tail and que[tail].first>=dp) tail--;
que[++tail] = {dp,j};
if(j-que[head].second>c) head++;
f[tag][j] = que[head].first + dis[j];
}
}
cout << (f[tag^1][n] < 0x3f3f3f3f3f3f3f3f ? f[tag^1][n] : -1) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
Educational Codeforces Round 19
标签:code turn 记录 += i+1 ati class 注意 end
原文地址:https://www.cnblogs.com/kikokiko/p/13516939.html