A: 将数分为k组使得每组不包含数值差为1的数
解:正整数可直接分为两组 奇数 偶数 符合题意, 所以给定数列有相邻就是2否则就是1
B1 / B2: 给定一每个点出度为1的图问每个点走到自己需要多少步
明显走到自己是个环, 并且环上答案都一样,递归求解即可
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e6 + 10;
typedef long long ll;
typedef long double ld;
const ll MOD = 1e9 + 7;
const int MX = 1e3 + 7;
int to[MAXN] = {0};
int ans[MAXN] = {0};
int step = 0, fa = 0;
void get(int now)
{
int rto = to[now];
++step;
if(rto != fa)
{
get(rto);
}
ans[now] = step;
}
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
//freopen("1.txt", "r", stdin);
int q;
cin >> q;
while(q--)
{
int n;
cin >> n;
fill(ans, ans + n + 10, 0);
for(int i = 1; i <= n; ++i)
{
cin >> to[i];
}
for(int i = 1; i <= n; ++i)
{
if(!ans[i])
{
step = 0, fa = i;
get(i);
}
}
for(int i = 1; i <= n; ++i)
{
cout << ans[i] << ' ';
}
cout << '\n';
}
return 0;
}
C:问最靠近N的三进制数
先找一个大于N的满三进制数, 从大往小贪心删除即可
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
typedef long long ll;
typedef long double ld;
const ll MOD = 1e9 + 7;
ll arr[MAXN] = {1}, p = 1;
ll pre[MAXN] = {1};
ll a[MAXN] = {0}, pa = 0, b[MAXN] = {0}, pb = 0;
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
//freopen("1.txt", "r", stdin);
for(int i = 1; ; ++i)
{
arr[p++] = arr[i - 1] * 3;
pre[i] = pre[i - 1] + arr[i];
//cout << arr[i] << ' ' << pre[i] << '\n';
if(arr[i] > 1e18)
break;
}
int q;
cin >> q;
while(q--)
{
ll n, sum;
cin >> n;
int rp = lower_bound(pre, pre + p, n) - pre;
sum = pre[rp];
for(int i = rp; i >= 0; --i)
{
if(sum - arr[i] >= n)
sum -= arr[i];
}
cout << sum << '\n';
}
return 0;
}
D1/D2: 给定一堆线段,问删最少的线段数使得每个点被覆盖最多k次
维护一个滑窗set保存覆盖当前点的所有线段 遍历全部点更新答案
首先当前点被覆盖多余k次 则无论如何也需要删掉当前点上的x - k条线段,这x - k条线段越往右延伸覆盖到下一个点的几率越大,所以每次碰见多k次的点,就把滑窗中最靠右的几个线段删掉并记录答案即可
对于每个点的覆盖次数, 可以用树状数组 / 线段树维护区间加和单点查询维护
/*
Zeolim - An AC a day keeps the bug away
*/
//#pragma GCC optimize(2)
//#pragma GCC ("-W1,--stack=128000000")
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
#define pb(x) push_back(x)
#define mem(x) memset(x, 0, sizof(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef std::pair <int, int> pii;
typedef std::vector <int> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 386910137;
const ull P = 13331;
const int MAXN = 2e5 + 1e4;
const int MX = 2e5 + 10;
int n, k;
struct bit
{
int c[MAXN << 1];
int lowbit(int pos) {return pos & -pos;}
void add(int pos, int val)
{ for( ; pos <= MX; pos += lowbit(pos)) c[pos] += val; }
int ask(int pos)
{
int ret = 0;
for( ; pos; pos -= lowbit(pos)) ret += c[pos];
return ret;
}
};
struct line
{
int x, y, id;
bool operator < (const line b) const { return y >= b.y; }
}lin[MAXN];
bool cmp(line a, line b) { return a.x < b.x; }
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
//freopen("1.txt", "r", stdin);
bit T;
cin >> n >> k;
for(int i = 1; i <= n; ++i)
{
int x, y;
cin >> x >> y;
lin[i] = line{x, y, i};
T.add(x, 1);
T.add(y + 1, -1);
}
sort(lin + 1, lin + n + 1, cmp);
vector <int> ans;
int p = 1;
set <line> ST;
for(int i = 1; i <= MX && p <= n; ++i)
{
int x = T.ask(i);
while(lin[p].x == i) { ST.insert(lin[p++]); }
auto it = ST.end();
while(ST.size() && (--it)->y < i)
{
ST.erase(it);
it = ST.end();
}
while(x > k)
{
it = ST.begin();
ans.push_back(it->id);
T.add(it->x, -1);
T.add(it->y + 1, 1);
ST.erase(it);
--x;
}
}
cout << ans.size() << '\n';
for(auto x : ans) { cout << x << ' '; }
return 0;
}
E 给两个数组 数组a是从i层到i+1层走路的时间, 数组b是从i层到i+1层坐电梯的时间,但是如果当前不在电梯里,需要等待c秒开门时间 问到达每层的最小时间
DP[MAXN][2]代表到第i层是走楼梯 0 还是坐电梯 1 走楼梯直接转移 坐电梯转移楼梯状态就需要加c秒等待时间
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
typedef long long ll;
typedef long double ld;
const ll MOD = 1e9 + 7;
ll ra[MAXN], rb[MAXN];
ll dp[MAXN][2] = {0};
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
//freopen("1.txt", "r", stdin);
ll n, c;
cin >> n >> c;
for(int i = 1; i < n; ++i)
cin >> ra[i];
for(int i = 1; i < n; ++i)
cin >> rb[i];
dp[0][1] = c;
for(int i = 1; i < n; ++i)
{
dp[i][0] = min(dp[i - 1][0] + ra[i], dp[i - 1][1] + ra[i]);
dp[i][1] = min(dp[i - 1][1] + rb[i], dp[i - 1][0] + rb[i] + c);
}
for(int i = 0; i < n; ++i)
{
cout << min(dp[i][0], dp[i][1]) << ' ';
}
return 0;
}