Codeforces Round #751 (Div. 2)
Codeforces Round #751 (Div. 2)
A. Two Subsequences
找一个字典序最小的字母并输出,再输出去掉第一个最小字母的原字符串即可,代码略。
B. Divine Array
给我们一个数组,不停变换,将数字变换为其在数组中出现的次数,题问第k次变换后第x位的数是什么。
简单枚举可知,数组会经过一定次数的变换后稳定,不会再改变,直接存储输出即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<sstream>
#include<cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PUU;
#define RUSH cin.tie(),cout.tie(),ios::sync_with_stdio(false)
#define pb push_back
#define eb emplace_back
#define pai acos(-1.0)
inline ll qmi(ll a,ll b,ll mod){
ll ans=1%mod;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans%mod;
}
inline ll inv(ll a,ll mod){
return qmi(a,mod-2,mod);
}
const int N=2010;
int a[N][N];
map<int,int> las;
int main(){
int _;
cin>>_;
while(_--){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[0][i];
for(int i=1;i<=n;i++){
las.clear();
for(int j=1;j<=n;j++) las[a[i-1][j]]++;
for(int j=1;j<=n;j++) a[i][j]=las[a[i-1][j]];
}
int q,pos,k;
cin>>q;
while(q--){
cin>>pos>>k;
cout<<a[min(k,n)][pos]<<endl;
}
}
return 0;
}
C. Array Elimination
给我们一个数组,让我们随意选其中k个数,使这k个数减去他们的异或和,最后使得数组元素都变为0,找出这些数k。
考虑拆分每个数的每一位,只需要每一位上1的个数都能被数k整除即可。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<double, double> PUU;
#define RUSH cin.tie(), cout.tie(), ios::sync_with_stdio(false)
#define pb push_back
#define eb emplace_back
#define pai acos(-1.0)
inline ll qmi(ll a, ll b, ll mod)
{
ll ans = 1 % mod;
while (b)
{
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans % mod;
}
inline ll inv(ll a, ll mod)
{
return qmi(a, mod - 2, mod);
}
const int N = 200010;
int a[N][25];
int ans[N];
int cnt[35];
int main()
{
int _;
cin >> _;
while (_--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
for (int j = 0; j < 30; j++)
if ((x >> j) & 1)
cnt[j]++;
}
for (int i = 1; i <= n; i++)
{
bool flag = true;
for (int j = 0; j < 30; j++)
{
if (cnt[j] % i != 0)
{
flag = false;
break;
}
}
if (flag)
cout << i << ' ';
}
for (int i = 0; i < 30; i++)
cnt[i] = 0;
cout << endl;
}
return 0;
}
D. Frog Traveler
一只青蛙在井底,在距离地面x米的地方可以往上跳[0,a[x]]米,设跳完之后离地面有y米,在下一次起跳之前会掉落b[y]米,问我们跳的最少次数以及路径。
直接bfs即可。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<double, double> PUU;
#define RUSH cin.tie(), cout.tie(), ios::sync_with_stdio(false)
#define pb push_back
#define eb emplace_back
#define pai acos(-1.0)
inline ll qmi(ll a, ll b, ll mod)
{
ll ans = 1 % mod;
while (b)
{
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans % mod;
}
inline ll inv(ll a, ll mod)
{
return qmi(a, mod - 2, mod);
}
//hha
const int N = 300010;
int a[N], b[N];
bool st[N];
int f[N];
int fr[N];
int n;
void out_pp(int x)
{
if (x >= n)
return;
out_pp(fr[x]);
cout << x << ' ';
}
bool bfs()
{
queue<int> q;
memset(st, 0, sizeof(st));
memset(f, 0x3f, sizeof(f));
st[n] = 1;
q.push(n);
f[n] = 0;
int dis = n;
while (q.size())
{
auto t = q.front(); // LAS DEPTH
q.pop();
int now = t + b[t]; // NOW DEPTH
// 可以跳 1~a[now] 最大跳到 now+a[now]
for (int to = min(now, dis - 1); to >= now - a[now]; to--)
{
if (to <= 0)
{
to = 0;
f[to] = f[t] + 1;
fr[to] = t;
cout << f[to] << endl;
out_pp(0);
return true;
}
f[to] = f[t] + 1;
fr[to] = t;
q.push(to);
}
dis = min(dis, now - a[now]);
}
return false;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int j = 1; j <= n; j++)
cin >> b[j];
if (bfs())
return 0;
else
return puts("-1") * 0;
}
E. Optimal Insertion
给一个长度为n的数组a和长度为m的数组b,让我们把数组b插入到a中,并且使得所产生的新的数组的逆序对个数最少。
如果要使得所产生的逆序对个数最少,那么b必定是在自身排序后再有序插入到a中,(小的在前面,大的在后面)防止与原数组自身产生新的逆序对。
这样只需要分治找到b中每一个数需要插入的位置即可,造出新数组之后用树状数组(或者归并排序)求逆序对即可。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<double, double> PUU;
#define RUSH cin.tie(), cout.tie(), ios::sync_with_stdio(false)
#define pb push_back
#define eb emplace_back
#define pai acos(-1.0)
inline ll qmi(ll a, ll b, ll mod)
{
ll ans = 1 % mod;
while (b)
{
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans % mod;
}
inline ll inv(ll a, ll mod)
{
return qmi(a, mod - 2, mod);
}
const int N = 2020100;
int a[N], b[N], pos[N];
int tr[N];
int c[N];
int d[N];
int n, m;
int prpr = 0;
inline int lowbit(int x)
{
return x & -x;
}
inline void add(int x)
{
for (int i = x; i <= prpr; i += lowbit(i))
tr[i]++;
}
inline void dadd(int x)
{
for (int i = x; i <= prpr; i += lowbit(i))
tr[i]--;
}
inline ll sum(int x)
{
ll res = 0;
for (int i = x; i; i -= lowbit(i))
res += tr[i];
return res;
}
inline int find(int x)
{
int l = 1, r = prpr;
while (l < r)
{
int mid = l + r >> 1;
if (d[mid] >= x)
r = mid;
else
l = mid + 1;
}
return l;
}
void get_pos(int a[], int b[], int pos[], int l, int r, int L, int R)
{
if (l > r)
return;
int mid = l + r >> 1;
int loc = L, minv = 0, now = 0;
for (int i = L + 1; i <= R; i++)
{
if (a[i - 1] > b[mid])
now++;
if (a[i - 1] < b[mid])
now--;
if (now < minv)
{
minv = now;
loc = i;
}
}
pos[mid] = loc;
get_pos(a, b, pos, l, mid - 1, L, loc);
get_pos(a, b, pos, mid + 1, r, loc, R);
}
int main()
{
RUSH;
int _;
cin >> _;
while (_--)
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
cin >> b[i];
sort(b + 1, b + 1 + m);
get_pos(a, b, pos, 1, m, 1, n + 1);
int cnt = 0, now = 0;
for (int i = 1; i <= m; i++)
{
while (pos[i] - 1 > now)
c[++cnt] = a[++now];
c[++cnt] = b[i];
}
while (now < n)
c[++cnt] = a[++now];
for (int i = 1; i <= n + m; i++)
d[i] = c[i];
sort(d + 1, d + 1 + n + m);
cnt = 1;
for (int i = 2; i <= n + m; i++)
{
if (d[i] != d[cnt])
d[++cnt] = d[i];
}
prpr = cnt;
ll res = 0;
for (int i = 1; i <= n + m; i++)
{
int x = find(c[i]);
res += sum(prpr) - sum(x);
add(x);
}
for (int i = 1; i <= n + m; i++)
{
int x = find(c[i]);
dadd(x);
}
cout << res << endl;
}
return 0;
}
By 泽浩巨巨

浙公网安备 33010602011771号