真 是 一 道 好 题
其实这道题并不难,可以用线段树过这题。
#include <bits/stdc++.h>
#define re register
#define lson (ind<<1)
#define rson (ind<<1|1)
using namespace std;
typedef long long ll;
const int maxn = 100005;
int n, a[maxn];
int l[maxn<<2], r[maxn<<2], mx[maxn<<2], mn[maxn<<2], tag[maxn<<2];
ll val[maxn<<2], ans;
inline ll read() {
ll ret = 0, flag = 1;
char ch = getchar();
while (ch > '9' || ch < '0') {
ch = getchar();
if (ch = '-') flag = -1;
}
while (ch <= '9' && ch >= '0') {
ret = (ret << 1) + (ret << 3) + (ch ^ '0');
ch = getchar();
}
return ret * flag;
}
inline void write(re ll num) {
if (num > 9) {
write(num/10);
}
putchar(num%10+'0');
}
inline void pushup(re int ind) {
val[ind] = val[lson] + val[rson];
mx[ind] = mx[lson];
mn[ind] = mn[rson];
}
inline void change(re int ind, re int v) {
mx[ind] += v; mn[ind] += v; tag[ind] += v; val[ind] += 1ll * v * (r[ind] - l[ind] + 1);
}
inline void build(re int le, re int ri, re int ind) {
if (le == ri) {
l[ind] = r[ind] = le;
val[ind] = mx[ind] = mn[ind] = a[le];
return;
}
re int mid = (le + ri) >> 1;
build(le, mid, lson);
build(mid+1, ri, rson);
l[ind] = le, r[ind] = ri;
pushup(ind);
}
inline void pushdown(re int ind) {
if (!tag[ind]) return;
change(lson, tag[ind]);
change(rson, tag[ind]);
tag[ind] = 0;
}
inline void update(re int x, re int y, re int v, re int ind) {
if (x > r[ind] || y < l[ind]) return;
else if (x <= l[ind] && y >= r[ind]) {
change(ind, v);
return;
}
re int mid = (l[ind]+r[ind])>>1;
pushdown(ind);
if (mid >= x) update(x, y, v, lson);
if (mid < y) update(x, y, v, rson);
pushup(ind);
}
inline ll query_sum(re int x, re int y, re int ind) {
if (x > r[ind] || y < l[ind]) return 0;
else if (x <= l[ind] && y >= r[ind]) {
return val[ind];
}
pushdown(ind);
return query_sum(x, y, lson) + query_sum(x, y, rson);
}
inline ll query_max(re int x, re int y, re int ind) {
if (x > r[ind] || y < l[ind]) return 0;
else if (x <= l[ind] && y >= r[ind]) {
return val[ind];
}
pushdown(ind);
return max(query_max(x, y, lson), query_max(x, y, rson));
}
inline ll query_min(re int x, re int y, re int ind) {
if (x > r[ind] || y < l[ind]) return 0x7fffffff;
else if (x <= l[ind] && y >= r[ind]) {
return val[ind];
}
pushdown(ind);
return min(query_min(x, y, lson), query_min(x, y, rson));
}
ll x, y;
int main() {
x = read(); y = read();
build(1, 100000, 1);
update(1, 1, x, 1);
update(2, 2, y, 1);
ans = query_sum(1, 2, 1);
write(ans); puts("");
return 0;
}
后来发现,神犇们还有更短的AC代码
半死不活的SPFA
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll head[100005], pre[100005], to[100005], val[100005], len;
ll dis[100005], vis[100005];
void insert(ll u, ll v, ll w) {
to[++len] = v; pre[len] = head[u]; val[len] = w; head[u] = len;
}
void SPFA(ll root) {
queue<ll> q;
q.push(root);
while (!q.empty()) {
ll x = q.front();
q.pop();
for (ll i = head[x]; i; i = pre[i]) {
ll y = to[i];
if (dis[y] > dis[x] + val[i]) {
dis[y] = dis[x] + val[i];
if (!vis[y]) {
q.push(y);
vis[y] = 1;
}
}
}
vis[x] = 0;
}
}
ll x, y;
int main() {
scanf("%lld %lld", &x, &y);
insert(1, 2, x);
insert(2, 3, y);
memset(dis, 0x7f, sizeof(dis));
dis[1] = 0;
SPFA(1);
printf("%lld
", dis[3]);
return 0;
}
还有巨佬用网络流AC此题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Edge{
ll pre, to, val;
}edge[100005];
ll head[100005], cur[100005], len;
ll d[100005];
ll s = 0, t = 3;
ll ans;
const ll inf = 0x7fffffffffffffff;
void insert(ll x, ll y, ll z) {
edge[++len].pre = head[x]; edge[len].to = y; edge[len].val = z; head[x] = len;
}
bool bfs() {
queue<ll> q;
memset(d, -1, sizeof(d));
d[s] = 1;
q.push(s);
ll x, y;
while (!q.empty()) {
x = q.front(); q.pop();
for (ll i = head[x]; i; i = edge[i].pre) {
y = edge[i].to;
if (d[y] == -1 && edge[i].val > 0) {
d[y] = d[x] + 1;
q.push(y);
}
}
}
if (d[t] == -1) return false;
memcpy(cur, head, sizeof(cur));
return true;
}
ll dfs(ll x, ll flow) {
if (x == t) return flow;
ll ret = 0, y, p;
for (ll &i = cur[x]; i; i = edge[i].pre) {
y = edge[i].to;
if (d[y] == d[x] + 1 && edge[i].val > 0) {
p = dfs(y, min(flow - ret, edge[i].val));
if (p) {
edge[i].val -= p;
edge[i^1].val += p;
ret += p;
if (ret == flow) return ret;
}
}
}
d[x] = -1;
return ret;
}
ll dinic() {
ll c = 0;
ll p;
while (bfs()) {
p = dfs(s, inf);
while (p) {
c += p;
p = dfs(s, inf);
}
}
return c;
}
ll x, y;
int main() {
scanf("%lld %lld", &x, &y);
insert(0, 1, x);
insert(1, 3, x);
insert(0, 2, y);
insert(2, 3, y);
ans = dinic();
printf("%lld
", ans);
return 0;
}
%%%orz
最小生成树
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Edge{
ll from, to, val;
}edge[100005];
ll len, fa[100005];
void insert(ll x, ll y, ll z) {
edge[++len].from = x; edge[len].to = y; edge[len].val = z;
}
ll x, y, ans;
bool cmp(Edge a, Edge b) {
return a.val < b.val;
}
ll get(ll x) {
if (x == fa[x]) return x;
else return fa[x] = get(fa[x]);
}
void kruskal() {
sort(edge + 1, edge + len + 1, cmp);
for (int i = 1; i <= 2; i++) fa[i] = i;
for (int i = 1; i <= len; i++) {
ll tx = get(edge[i].from);
ll ty = get(edge[i].to);
if (tx != ty) {
fa[tx] = ty;
ans += edge[i].val;
}
}
}
int main() {
scanf("%lld %lld", &x, &y);
insert(1, 2, x);
insert(2, 3, y);
kruskal();
printf("%lld
", ans);
return 0;
}
一句话代码
#include <iostream>
#define What using
#define a namespace
#define fantastic std;
#define problem signed
#define A main(){
#define Plus int
#define B x,y;
#define Problem cin>>x>>y;
#define is cout<<x+y; }
What a fantastic problem A Plus B Problem is