A 玉米大炮 — 二分
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 200010;
int n, m;
int a[N], b[N];
bool check(int mid)
{
int res = 0;
for(int i = 1; i <= n; i ++)
{
res += a[i] * (int)(mid / b[i]) + a[i];
if(res >= m) return true;
}
return res >= m;
}
signed main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++) cin >> a[i] >> b[i];
int l = 0, r = 2e18;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << r << '\n';
}
B 逆序对计数 — 预处理 + 树状数组
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 6010;
int n, q;
int tr[N], a[N];
int f[N][N];
int lowbit(int x)
{
return x & -x;
}
void add(int x, int v)
{
for(int i = x; i <= n; i += lowbit(i)) tr[i] += v;
}
int query(int x)
{
int res = 0;
for(int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++)
{
for(int j = i; j <= n; j ++)
{
f[i][j] = f[i][j - 1] + query(n) - query(a[j]);
add(a[j], 1);
}
for(int j = 0; j <= n; j ++) tr[j] = 0;
}
int sum = f[1][n];
cin >> q;
while(q --)
{
int l, r; cin >> l >> r;
int res = sum - f[l][r] + (r - l + 1) * (r - l) / 2 - f[l][r];
cout << res << '\n';
}
}
C 区间操作 — 线段树 + 线性筛
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
#include<set>
using namespace std;
#define int long long
const int N=4000010;
int b[N];
int primes[N], idx = 0, f[N];
bool st[N];
struct node
{
int l, r, sum;
int add;
}tr[N << 2];
void init(int n){
for(int i = 2 ; i <= n ; i ++){
if(!st[i]) primes[idx ++] = i, f[i] = 1;
for(int j = 0; primes[j] * i <= n; j ++)
{
st[i * primes[j]] = 1 ;
f[i * primes[j]] = f[i] + 1;
if(i % primes[j] == 0) break;
}
}
}
void pushup(node &u, node &l, node &r)
{
u.sum = l.sum + r.sum;
}
void pushup(int u)
{
pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void pushdown(int u)
{
if(tr[u].add)
{
tr[u << 1].sum += tr[u].add * (tr[u << 1].r - tr[u << 1].l + 1);
tr[u << 1 | 1].sum += tr[u].add * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1);
tr[u << 1].add += tr[u].add;
tr[u << 1 | 1].add += tr[u].add;
tr[u].add = 0;
}
}
void build(int u, int l, int r)
{
tr[u] = {l, r};
if(l == r)
{
tr[u].sum = b[l];
return ;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int v)
{
if(tr[u].l >= l && tr[u].r <= r)
{
tr[u].sum += v * (tr[u].r - tr[u].l + 1);
tr[u].add += v;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(u << 1, l, r, v);
if(r > mid) modify(u << 1 | 1, l, r, v);
pushup(u);
}
int query(int u, int l, int r)
{
if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
int res = 0;
int mid = tr[u].l + tr[u].r >> 1;
pushdown(u);
if(l <= mid) res += query(u << 1, l, r);
if(r > mid) res += query(u << 1 | 1, l, r);
return res;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
init(N - 1);
int n; cin >> n;
for(int i = 1; i <= n; i ++) cin >> b[i], b[i] = f[b[i]];
build(1, 1, n);
int q; cin >> q;
while(q --)
{
int op, l , r;
cin >> op >> l >> r;
if(op == 1) cout << query(1, l, r) << '\n';
else
{
int x; cin >> x;
modify(1, l, r, f[x]);
}
}
}
D 小蓝的新技能 — 数学优化暴力
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 100010;
signed main()
{
int n; cin >> n;
int res = 0;
for(int gcd = 1; gcd * gcd * gcd <= n; gcd ++)
{
for(int a = gcd; a * a * a <= n; a += gcd)
{
int lcm3 = n - gcd * gcd * gcd;
int l = 1, r = 1e6;
while(l < r)
{
int mid = l + r >> 1;
if(mid * mid * mid >= lcm3) r = mid;
else l = mid + 1;
}
if(r * r * r != lcm3) continue;
int lcm = r;
int b = lcm * gcd / a;
if( __gcd(a, b) == gcd && a * b == lcm * gcd) res ++;
}
}
cout << res << '\n';
}
F 爱学习的小蓝—签到
#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int N = 100010;
int a[10] = {2, 8, 8, 18, 18, 32, 32};
void solve()
{
int x; cin >> x;
int res = 0;
for(int i = 0; i < 8; i ++)
{
if(res >= x)
{
cout << i << '\n';
return ;
}
res += a[i];
}
}
signed main()
{
int T; cin >> T;
while(T --) solve();
}
H 树上问题 — 树形dp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int N = 100010, M = 4000000;
int n;
int a[N], down[N], up[N];
vector<int> g[N];
int res = 0;
void dfs1(int u, int fa)
{
int maxv = 0;
for(auto v : g[u])
{
if(v == fa) continue;
dfs1(v, u);
maxv = max(maxv, down[v]);
}
down[u] = maxv + a[u];
}
void dfs2(int u, int fa)
{
int d1 = 0, d2 = 0;
for(auto v : g[u])
{
if(v == fa) continue;
if(down[v] >= d1)
{
d2 = d1;
d1 = down[v];
}
else if(down[v] > d2) d2 = down[v];
}
for(auto v : g[u])
{
if(v == fa) continue;
if(down[v] == d1)
up[v] = max({up[v], up[u] + a[v], d2 + a[u] + a[v]});
else
up[v] = max({up[v], up[u] + a[v], d1 + a[u] + a[v]});
dfs2(v, u);
}
}
int f[N];
void dfs3(int u, int fa)
{
int m1 = 0, m2 = 0;
int maxv = 0;
for(auto v : g[u])
{
if(v == fa) continue;
dfs3(v, u);
int t = max(up[v], down[v]);
if(t >= m1)
{
m2 = m1;
m1 = t;
}
else if(t > m2) m2 = t;
maxv = max(maxv, f[v]);
}
f[u] = m1 + max(down[u], up[u]);
res = max({res, m1 + m2 + max(down[u], up[u]), maxv + max(down[u], up[u])});
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i < n; i ++)
{
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1, -1);
dfs2(1, -1);
dfs3(1, -1);
cout << res << '\n';
}
I 旅行—最短路
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define int long long
typedef pair<int, int>PII;
const int N = 400010, M = 4000000;
vector<PII> g[N];
int n, m, x;
int dist[N];
bool st[N];
int dij()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII> >heap;
heap.push({0,1});
while(heap.size())
{
auto [dis,u] = heap.top();
heap.pop();
if(st[u]) continue;
st[u] = true;
for(auto [v, w] : g[u])
{
if(dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
heap.push({dist[v], v});
}
}
}
return min(dist[n], dist[n + n]);
}
signed main()
{
cin >> n >> m >> x;
for(int i = 1; i <= m; i ++)
{
int a, b, c;
cin >> a >> b >> c;
g[a + n].push_back({b, c});
g[b + n].push_back({a, c});
g[a].push_back({b + n, c + x});
g[b].push_back({a + n, c + x});
}
cout << dij() << '\n';
}
J 神奇数字—数学
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define int long long
const int N = 100010;
void solve()
{
int a[3];
cin >> a[0] >> a[1] >> a[2];
if(a[0] == a[1] && a[1] == a[2])
{
cout << -1 << '\n';
return ;
}
sort(a, a + 3);
int n = __gcd(a[2] - a[1], a[1] - a[0]);
vector<int>res;
for(int i = 1; i <= n / i; i ++)
{
if(n % i == 0)
{
res.push_back(i);
if(n != i * i) res.push_back(n / i);
}
}
sort(res.begin(), res.end());
for(auto x : res) cout << x << ' ';
cout << '\n';
}
signed main()
{
int T; cin >> T;
while(T --) solve();
}
L 合成游戏 — 数学
#include<iostream>
using namespace std;
#define int long long
const int N = 100010, mod = 1e9 + 7;
int n;
int a[N], f[N], g[N];
signed main(){
cin >> n;
f[1] = f[2] = 1;
for(int i = 3; i <= n; i ++)
{
if(i % 2 == 1) f[i] = i * f[i-1] % mod;
else f[i] = f[i - 2] * (i - 1) % mod;
}
g[1] = g[2] = 1;
for(int i = 3; i <= n; i ++)
g[i] = f[i] * g[i / 2] % mod;
for(int i = 1; i <= n; i ++)
{
int x; cin >> x;
cout << g[x] << '\n';
}
}