线段树:
一、单点修改,区间查询
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 100;
int n, Q;
int a[maxn];
int suma[maxn];
typedef struct
{
int l, r;
int sum;
}T;
T t[maxn << 1];
inline void build(int rt, int l, int r)
{
t[rt].l = l;
t[rt].r = r;
if (l == r)
{
t[rt].sum = a[l];
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
t[rt].sum = t[rt << 1].sum + t[rt << 1 | 1].sum;
}
inline int interval_add(int rt, int l, int r)
{
if (t[rt].l >= l && t[rt].r <= r)return t[rt].sum;
if (t[rt].l > r || t[rt].r < l)return 0;
int temp = 0;
if (t[rt << 1].r >= l)temp += interval_add(rt << 1, l, r);
if (t[rt << 1 | 1].l <= r)temp += interval_add(rt << 1 | 1, l, r);
return temp;
}
inline void point_modify(int rt, int pos, int val)
{
if (t[rt].l == t[rt].r)
{
t[rt].sum += val;
return;
}
if (pos <= t[rt << 1].r)point_modify(rt << 1, pos, val);
else point_modify(rt << 1 | 1, pos, val);
t[rt].sum = t[rt << 1].sum + t[rt << 1 | 1].sum;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)cin >> a[i], suma[i] = suma[i - 1] + a[i];
build(1, 1, n);
cin >> Q;
while (Q--)
{
bool f;
cin >> f;
if (f)
{
int l, r;
cin >> l >> r;
cout << interval_add(1, l, r) << "\n";
}
else
{
int p, v;
cin >> p >> v;
point_modify(1, p, v);
a[p] += v;
for (int i = 1; i <= n; i++)cout << a[i] << " ";
cout << "\n";
}
}
}
二.区间修改,单点查询
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 100;
int n, Q;
int a[maxn];
int suma[maxn];
typedef struct
{
int l, r;
int sum;
}T;
T t[maxn << 1];
inline void build(int rt, int l, int r)
{
t[rt].l = l;
t[rt].r = r;
if (l == r)
{
t[rt].sum = a[l];
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
}
inline void interval_modify(int rt, int l, int r, int val)
{
if (t[rt].l >= l && t[rt].r <= r)
{
t[rt].sum += val;
return;
}
int mid = t[rt].l + t[rt].r >> 1;
if (l <= mid)interval_modify(rt << 1, l, r, val);
if (r > mid)interval_modify(rt << 1 | 1, l, r, val);
}
inline int point_ask(int rt, int pos)
{
int ans = 0;
ans += t[rt].sum;
if (t[rt].l == t[rt].r)return ans;
int mid = t[rt].l + t[rt].r >> 1;
if (pos <= mid) ans += point_ask(rt << 1, pos);
if (pos > mid)ans += point_ask(rt << 1 | 1, pos);
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n; cin >> Q;
for (int i = 1; i <= n; i++)cin >> a[i], suma[i] = suma[i - 1] + a[i];
build(1, 1, n);
while (Q--)
{
bool f;
cin >> f;
if (f)
{
int l, r, v;
cin >> l >> r >> v;
interval_modify(1, l, r, v);
for (int i = l; i <= r; i++)a[i] += v;
for (int i = 1; i <= n; i++)cout << a[i] << " ";
cout << "\n";
}
else
{
int pos;
cin >> pos;
cout << point_ask(1, pos) << "\n";
}
}
return 0;
}
扫描线法
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
typedef struct line
{
double x, y1, y2;
int c;
bool friend operator <(line p, line q)
{
return p.x < q.x;
}
}A;
A a[maxn << 1];
typedef struct tree
{
int l, r;
int cnt;
double len;
}T;
T t[maxn << 2];
int n;
double raw[maxn << 1];
int cnt;
double ans;
int val[maxn << 1][2];
inline void build(int rt, int l, int r)
{
t[rt].l = l;
t[rt].r = r;
t[rt].cnt = 0;
t[rt].len = 0;
if (l == r)return;
int mid = l + r >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
}
void push_up(int rt)
{
if (t[rt].cnt > 0)t[rt].len = raw[t[rt].r + 1] - raw[t[rt].l];
else if (t[rt].l == t[rt].r)t[rt].len = 0;
else t[rt].len = t[rt << 1].len + t[rt << 1 | 1].len;
}
void interval_modify(int rt, int l, int r, int val)
{
if (t[rt].l >= l && t[rt].r <= r)
{
t[rt].cnt += val;
push_up(rt);
return;
}
int mid = t[rt].l + t[rt].r >> 1;
if (l <= mid)interval_modify(rt << 1, l, r, val);
if (r > mid)interval_modify(rt << 1 | 1, l, r, val);
push_up(rt);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int casenum = 0;
while (cin >> n && n)
{
cnt = 0;
ans = 0;
for (int i = 1; i <= n; i++)
{
double x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
a[i * 2 - 1] = { x1,y1,y2,1 };
a[i * 2] = { x2,y1,y2,-1 };
raw[++cnt] = y1;
raw[++cnt] = y2;
}
sort(a + 1, a + 1 + 2 * n);
sort(raw + 1, raw + 1 + cnt);
cnt = unique(raw + 1, raw + 1 + cnt) - (raw + 1);
for (int i = 1; i <= n * 2; i++)
{
val[i][0] = lower_bound(raw + 1, raw + 1 + cnt, a[i].y1) - raw;
val[i][1] = lower_bound(raw + 1, raw + 1 + cnt, a[i].y2) - raw;
}
build(1, 1, cnt);
for (int i = 1; i <= 2 * n; i++)
{
interval_modify(1, val[i][0], val[i][1] - 1, a[i].c);
ans += (a[i + 1].x - a[i].x) * t[1].len;
}
cout << "Test case #" << ++casenum << "\n";
cout << "Total explored area: " << fixed << setprecision(2) << ans << "\n";
cout << "\n";
}
return 0;
}
单点修改,区间查询最大子段和
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 100;
int n, Q;
int a[maxn];
int suma[maxn];
typedef struct node
{
int l, r;
int sum;
int dat;
int lmax, rmax;
node()
{
l = r = sum = dat = lmax = rmax = 0;
}
}T;
T t[maxn << 2];
inline void build(int rt, int l, int r)
{
t[rt].l = l;
t[rt].r = r;
if (l == r)
{
t[rt].sum = a[l];
t[rt].lmax = t[rt].rmax = t[rt].dat = a[l];
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
t[rt].sum = t[rt << 1].sum + t[rt << 1 | 1].sum;
t[rt].lmax = max(t[rt << 1].lmax, t[rt << 1].sum + t[rt << 1 | 1].lmax);
t[rt].rmax = max(t[rt << 1 | 1].rmax, t[rt << 1].rmax + t[rt << 1 | 1].sum);
t[rt].dat = max(t[rt << 1].dat, t[rt << 1 | 1].dat);
t[rt].dat = max(t[rt].dat, t[rt << 1].rmax + t[rt << 1 | 1].lmax);
}
inline void point_modify(int rt, int pos, int val)
{
if (t[rt].l == t[rt].r)
{
t[rt].sum = t[rt].dat = t[rt].lmax = t[rt].rmax = val;
return;
}
int mid = t[rt].l + t[rt].r >> 1;
if (pos <= mid)point_modify(rt << 1, pos, val);
else point_modify(rt << 1 | 1, pos, val);
t[rt].sum = t[rt << 1].sum + t[rt << 1 | 1].sum;
t[rt].lmax = max(t[rt << 1].lmax, t[rt << 1].sum + t[rt << 1 | 1].lmax);
t[rt].rmax = max(t[rt << 1 | 1].rmax, t[rt << 1].rmax + t[rt << 1 | 1].sum);
t[rt].dat = max(t[rt << 1].dat, t[rt << 1 | 1].dat);
t[rt].dat = max(t[rt].dat, t[rt << 1].rmax + t[rt << 1 | 1].lmax);
return;
}
T interval_ask(int rt, int l, int r)
{
//此时的ask函数返回的是临时开的T,想一想为什么,如果是void类型ask,每次ask一个区间(l,r)dat,lmax,rmax都会随着l,r不同而修改,一定会影响后续ask
if (t[rt].l >= l && t[rt].r <= r)return t[rt];
int mid = t[rt].l + t[rt].r >> 1;
if (l <= mid && r > mid)
{
T tt, tl, tr;
tl = interval_ask(rt << 1, l, r);
tr = interval_ask(rt << 1 | 1, l, r);
tt.sum = tl.sum + tr.sum;
tt.lmax = max(tl.lmax, tl.sum + tr.lmax);
tt.rmax = max(tr.rmax, tl.rmax + tr.sum);
tt.dat = max(tl.dat, tr.dat);
tt.dat = max(tt.dat, tl.rmax + tr.lmax);
return tt;
}
else if (l <= mid)
{
return interval_ask(rt << 1, l, r);
}
else if (r > mid)
{
return interval_ask(rt << 1 | 1, l, r);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> Q;
for (int i = 1; i <= n; i++)cin >> a[i];
build(1, 1, n);
while (Q--)
{
int k, x, y;
cin >> k >> x >> y;
if (k & 1)
{
if (x > y)swap(x, y);
T ans = interval_ask(1, x, y);
cout << ans.dat << "\n";
}
else
{
point_modify(1, x, y);
}
}
return 0;
}
图论补充:第K短路(A*)
//Made In Heaven
#pragma GCC optimize(3, "Ofast", "inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 1000;
int n, m;
int S, E, K, T;
int dis[maxn];
int h1[maxn], h2[maxn];
bool vis1[maxn];
int num1, num2;
typedef struct
{
int nt, to, w;
}EDGE;
EDGE e1[maxn], e2[maxn];
void add1(int u, int v, int w)
{
e1[++num1].w = w;
e1[num1].to = v;
e1[num1].nt = h1[u];
h1[u] = num1;
}
void add2(int v, int u, int w)
{
e2[++num2].w = w;
e2[num2].to = v;
e2[num2].nt = h2[u];
h2[u] = num2;
}
typedef pair<int, int>P;
//反向建边dj T->S
void dj()
{
memset(dis, 0x3f, sizeof(dis));
dis[E] = 0;
priority_queue<P, vector<P>, greater<P> >q;
q.push(make_pair(dis[E], E));
while (!q.empty())
{
P p = q.top();
q.pop();
int u = p.second;
int diss = p.first;
if (vis1[u])continue;
vis1[u] = 1;
for (int i = h2[u]; i; i = e2[i].nt)
{
int v = e2[i].to;
if (dis[v] > diss + e2[i].w)
{
dis[v] = diss + e2[i].w;
q.push(make_pair(dis[v], v));
}
}
}
}
typedef pair<int, P>PP;
int A_start()
{
if (dis[S] >= 0x3f3f3f3f)return -1;
priority_queue<PP, vector<PP>, greater<PP> >q;
q.push(make_pair(dis[S], make_pair(0, S)));
int cnt = 0;
while (!q.empty())
{
PP p = q.top();
q.pop();
int u = p.second.second;
int diss = p.second.first;
if (u == E)cnt++;
if (cnt == K)return diss;
for (int i = h1[u]; i; i = e1[i].nt)
{
int v = e1[i].to;
q.push(make_pair(diss + e1[i].w + dis[v], make_pair(diss + e1[i].w, v)));
}
}
return -1;
}
void init() {
num1 = num2 = 0;
memset(vis1, 0, sizeof vis1);
memset(h1, 0, sizeof h1);
memset(h2, 0, sizeof h2);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (cin >> n >> m) {
init();
cin >> S >> E >> K >> T;
if (S == E)K++;
while (m--)
{
int u, v, w;
cin >> u >> v >> w;
add1(u, v, w);
add2(u, v, w);
}
dj();
int ans = A_start();
if (ans == -1 || ans > T)cout << "Whitesnake!\n";
else cout << "yareyaredawa\n";
}
return 0;
}