BD202301·公园
可以先
b
f
s
bfs
bfs统计一下
t
,
f
t,f
t,f到达每个点的距离,还有
n
n
n到达其他点的距离即其他点到达
n
n
n的距离 然后枚举每个点 直接计算得到最小值即可
注意特判有人无法到达
n
n
n的情况
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 4e4 + 7;
const int mod = 998244353;
int t,f,n,m;
int te,fe,s;
vector<int> g[N];
int d1[N],d2[N],d3[N];
void bfs(){
queue<int> q1,q2,q3;
q1.push(t);
q2.push(f);
q3.push(n);
vector<int> st1(n + 1,0),st2(n + 1,0),st3(n + 1,0);
st1[t] = 1,st2[f] = 1,st3[n] = 1;
for(int i = 1;i <= n;i ++){
d1[i] = 500000;
d2[i] = 500000;
d3[i] = 500000;
}
d1[t] = 0,d2[f] = 0,d3[n] = 0;
while(q1.size()){
auto x = q1.front();
q1.pop();
for(auto son : g[x]){
if(st1[son]) continue;
st1[son] = 1;
q1.push(son);
d1[son] = min(d1[son],d1[x] + 1);
}
}
while(q2.size()){
auto x = q2.front();
q2.pop();
for(auto son : g[x]){
if(st2[son]) continue;
st2[son] = 1;
q2.push(son);
d2[son] = min(d2[son],d2[x] + 1);
}
}
while(q3.size()){
auto x = q3.front();
q3.pop();
for(auto son : g[x]){
if(st3[son]) continue;
st3[son] = 1;
q3.push(son);
d3[son] = min(d3[son],d3[x] + 1);
}
}
}
void solve(){
cin >> te >> fe >> s;
cin >> t >> f >> n >> m;
for(int i = 0;i < m;i ++){
int u,v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
bfs();
if(d3[t] == 500000 || d3[f] == 500000){
cout << -1 << endl;
return;
}
int mn = d3[t] * te + d3[f] * fe;
for(int i = 1;i <= n;i ++){
int cnt1 = d1[i] * te;
int cnt2 = d2[i] * fe;
int cnt3 = d3[i] * (te + fe - s);
mn = min(mn,cnt1 + cnt2 + cnt3);
}
cout << mn << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202302·蛋糕划分
二进制形式枚举横切
二分结果
然后依次枚举竖的时候每列部分加上前边没被分开部分的和 看是否符合二分的结果 如果不符合 那么就在此处前边切开 如果单纯此部分就不符合 那么说明二进制枚举的横切情况就不符合
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 25;
const int mod = 998244353;
int n,k;
int a[N][N];
int pre[N][N];
int mx;
int cal(int x1,int y1,int x2,int y2){
return pre[x2][y2] - pre[x2][y1 - 1] - pre[x1 - 1][y2] + pre[x1 - 1][y1 - 1];
}
int check(int x){
if(mx > x) return 1;
int sumk = 0;
for(int i = 0;i < (1 << (n - 1));i ++){
int cp = i;
int sflag = 0;
vector<int> p;
int pos = 0;
while(cp){
pos ++;
if(cp & 1) p.push_back(pos);
cp /= 2;
}
if(p.size() > k) continue;
p.push_back(n);
vector<int> val(p.size() + 3,0);
int sumk = k - p.size() + 1;
for(int j = 1;j <= n;j ++){
int x1 = 1,y1 = j,y2 = j;
int pval = 1;
int fg = 0;
int flag = 0;
vector<int> sb;
for(auto t : p){
if(x1 > n) break;
int cnt = cal(x1,y1,t,y2);
x1 = t + 1;
sb.push_back(cnt);
if(cnt > x){
flag = 1;
break;
}
if(!fg) val[pval] += cnt;
else val[pval] = cnt;
if(val[pval] > x){
fg = 1;
sumk --;
for(int k = 1;k < pval;k ++) val[k] = sb[k - 1];
val[pval] = cnt;
}
pval ++;
}
if(flag){
sflag = 1;
break;
}
}
if(!sflag && sumk >= 0) return 0;
}
return 1;
}
void solve(){
cin >> n >> k;
mx = -1;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++){
cin >> a[i][j];
mx = max(mx,a[i][j]);
}
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++) pre[i][j] = a[i][j] + pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1];
}
int l = -1,r = n * n * mx;
while(l + 1 != r){
int mid = l + r >> 1;
if(check(mid)) l = mid;
else r = mid;
}
cout << r << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202303·第五维度
首先特判下如果
v
v
v 不为零的人
≤
\leq
≤ 1 那么就是 -1
其他二分算一下能完成多少 然后减去最大的然后 return 判断即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 1e5 + 7;
const int mod = 998244353;
int n,m;
struct node{
int s;
int v;
} a[N];
int check(int x){
__int128 sum = 0;
vector<int> v;
for(int i = 0;i < n;i ++){
int cnt;
if(x <= a[i].s) cnt = 0;
else cnt = (x - a[i].s) * a[i].v;
v.push_back(cnt);
sum += cnt;
}
int mx = *max_element(v.begin(),v.end());
sum -= mx;
return sum <= m;
}
void solve(){
cin >> n >> m;
for(int i = 0;i < n;i ++) cin >> a[i].s >> a[i].v;
int cnt = 0;
for(int i = 0;i < n;i ++){
if(a[i].v) cnt ++;
}
if(cnt < 2){
cout << -1 << endl;
return;
}
int l = 0,r = 5e9;
while(l + 1 != r){
int mid = l + r >> 1;
if(check(mid)) l = mid;
else r = mid;
}
cout << r << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202305·糖果促销
首先第一种方法 很明显的二分 去特判下 p = 1 即可
第二种则直接计算 显然想吃
k
k
k 块糖 就会产生
k
k
k 个糖纸 最后一个吃的糖肯定不参与糖纸的置换 所以参与糖纸置换的仅有
k
−
1
k-1
k−1个糖纸 那么 答案即
k
−
(
k
−
1
)
/
p
k-(k-1)/p
k−(k−1)/p
code1:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; cin >> _T; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 3e5 + 7;
const int mod = 998244353;
int p,k;
int check(int x){
int sum = x;
while(x / p){
sum += x / p;
x = x / p + x % p;
}
return sum < k;
}
void solve(){
cin >> p >> k;
if(!k){
cout << 0 << endl;
return;
}
if(p == 1){
cout << 1 << endl;
return;
}
int l = 0,r = k;
while(l + 1 != r){
int mid = l + r >> 1;
if(check(mid)) l = mid;
else r = mid;
}
cout << r << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
code2:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; cin >> _T; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 3e5 + 7;
const int mod = 998244353;
int p,k;
void solve(){
cin >> p >> k;
if(!k){
cout << k << endl;
return;
}
int ans = k - (k - 1) / p;
cout << ans << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202309·星际航行
易得出以中位数去操作为最优
那么依次枚举谁为
d
=
1
d=1
d=1的等差数列即可 然后以中位数向左右扩散为等差
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 3e5 + 7;
const int mod = 998244353;
int n;
int x[N],y[N],z[N];
void solve(){
cin >> n;
for(int i = 0;i < n;i ++) cin >> x[i] >> y[i] >> z[i];
sort(x,x + n),sort(y,y + n),sort(z,z + n);
int p = n / 2;
int mn = 1e18;
int sum1 = 0;
for(int i = 0;i < n;i ++){
sum1 += abs(x[i] - x[p]);
sum1 += abs(y[i] - y[p]);
sum1 += abs(z[p] + i - p - z[i]);
}
int sum2 = 0;
for(int i = 0;i < n;i ++){
sum2 += abs(x[i] - x[p]);
sum2 += abs(z[i] - z[p]);
sum2 += abs(y[p] + i - p - y[i]);
}
int sum3 = 0;
for(int i = 0;i < n;i ++){
sum3 += abs(z[i] - z[p]);
sum3 += abs(y[i] - y[p]);
sum3 += abs(x[p] + i - p - x[i]);
}
mn = min({mn,sum1,sum2,sum3});
cout << mn << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202311·夏日漫步
每个位置最多只有三个可以移动的方向 bfs即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 3e5 + 7;
const int mod = 998244353;
int n;
map<pair<int,int>,int> g;
int d[N];
int dx[] = {1,-1};
int a[N];
void bfs(){
memset(d,0x3f3f3f,sizeof d);
d[n] = n - 1;
d[1] = 0;
queue<pair<int,int>> q;
q.push({a[1],1});
vector<int> st(n + 2,0);
st[1] = 1;
while(q.size()){
auto x = q.front();
q.pop();
int x1 = x.second + 1;
int x2 = x.second - 1;
int x3 = g[{x.first,x.second}];
if(!st[x1] && x1 > 0 && x1 <= n && d[x.second] + 1 < d[x1]){
d[x1] = d[x.second] + 1;
q.push({a[x1],x1});
st[x1] = 1;
}
if(!st[x2] && x2 > 0 && x2 <= n && d[x.second] + 1 < d[x2]){
d[x2] = d[x.second] + 1;
q.push({a[x2],x2});
st[x2] = 1;
}
if(!st[x3] && x3){
d[x3] = min(d[x3],d[x.second] + 1);
q.push({x.first,x3});
st[x3] = 1;
}
}
}
void solve(){
cin >> n;
map<int,int> mp;
for(int i = 1;i <= n;i ++){
cin >> a[i];
if(mp.find(a[i]) != mp.end()){
g[{a[i],mp[a[i]]}] = i;
}
mp[a[i]] = i;
}
bfs();
cout << d[n] << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202314·跑步
统计一下每个位置的最小 v
然后从后往前开始看 如果位置相同或者 v 比当前位置 v要大就可以追上
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 3e5 + 7;
const int mod = 998244353;
int n;
pair<int,int> p[N];
void solve(){
cin >> n;
for(int i = 1;i <= n;i ++) cin >> p[i].first >> p[i].second;
sort(p + 1,p + 1 + n);
map<int,int> mp;
for(int i = 1;i <= n;i ++){
if(mp[p[i].first]) continue;
mp[p[i].first] = p[i].second;
}
int mx = 1;
for(int i = n;i > 0;){
int j = i;
int V = mp[p[j].first];
int P = p[j].first;
while(j > 0 && ((P == p[j - 1].first) || V < mp[p[j - 1].first])) j --;
mx = max(i - j + 1,mx);
i = j - 1;
}
cout << mx << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202321·新材料
直接遇到出现过得数就与上一次出现的位置距离看是否小于等于 k k k即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 1e5 + 7;
const int mod = 998244353;
int n,k;
void solve(){
cin >> n >> k;
map<int,int> mp;
map<int,int> mp2;
int ans = 0;
for(int i = 1;i <= n;i ++){
int x; cin >> x;
if(!mp[x]) mp[x] = i;
else{
if(i - mp[x] <= k){
if(mp2[x]) continue;
mp2[x] = 1;
ans ^= x;
} else{
mp[x] = i;
}
}
}
cout << ans << endl;
}
signed main(){
fast();
_
solve();
return 0;
}
BD202319·新的阶乘
筛一下质数 然后暴力跑质数的倍数 去统计倍数中含有此质数的指数
#define int long long 等于 喜提 tle
code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define F first
#define S second
#define lowbit(x) ((x) & (-x))
#define _ int _T; _T = 1; while(_T --)
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
using namespace std;
typedef pair<int, int> PII;
typedef pair<char,int> PCI;
const int N = 1e7 + 7;
const int mod = 998244353;
int st[N];
int x;
int prime[N];
int cnt;
void get_prime(int n){
for(int i = 2;i <= n;i ++){
if(st[i]) continue;
prime[cnt ++] = i;
for(int j = i + i;j <= n;j += i) st[j] = 1;
}
}
void solve(){
int x; cin >> x;
get_prime(x);
cout << "f(" << x << ")=";
for(int i = 0;i < cnt;i ++){
int nw = prime[i];
long long sum = x - (nw - 1);
for(int j = nw + nw;j <= x;j += nw){
int k = j;
int sb = 0;
while(k % nw == 0){
sb ++;
k /= nw;
}
sum += sb * (x - (j - 1));
}
cout << nw;
if(sum > 1) cout << "^" << sum;
if(i != cnt - 1) cout << "*";
}
}
signed main(){
fast();
_
solve();
return 0;
}