持续咕咕咕。
数据结构
线段树。
#include<bits/stdc++.h>
const int maxn = 1001000;
typedef long long ll;
int n,q,a[maxn];
ll tree[maxn << 2],tg[maxn << 2];
inline void put(int cur,ll v,int len){ tree[cur] += v * len,tg[cur] += v; }
inline void down(int cur,int len){
if(tg[cur])
put(cur << 1,tg[cur],len + 1 >> 1),put(cur << 1 | 1,tg[cur],len >> 1),tg[cur] = 0;
}
inline void up(int cur){ tree[cur] = tree[cur << 1] + tree[cur << 1 | 1]; }
inline void modify(int cur,int ql,int qr,int v,int l=1,int r=n){
if(ql <= l && r <= qr) return put(cur,v,r-l+1);
int mid = l + r >> 1; down(cur,r-l+1);
if(ql <= mid) modify(cur << 1,ql,qr,v,l,mid);
if(mid < qr) modify(cur << 1 | 1,ql,qr,v,mid+1,r);
up(cur);
}
inline ll query(int cur,int ql,int qr,int l=1,int r=n){
if(ql <= l && r <= qr) return tree[cur];
int mid = l + r >> 1; ll ans = 0; down(cur,r-l+1);
if(ql <= mid) ans += query(cur << 1,ql,qr,l,mid);
if(mid < qr) ans += query(cur << 1 | 1,ql,qr,mid+1,r);
return ans;
}
inline void build(int cur,int l,int r){
if(l == r) return void(tree[cur] = a[l]);
int mid = l + r >> 1;
build(cur << 1,l,mid),build(cur << 1 | 1,mid + 1,r),up(cur);
}
int main(){
std::ios::sync_with_stdio(false),std::cin.tie(0);
std::cin >> n >> q;
for(int i=1;i<=n;++i) std::cin >> a[i];
build(1,1,n);
for(int i=1,op,l,r,x;i<=q;++i){
std::cin >> op >> l >> r;
if(op == 1)
std::cin >> x,modify(1,l,r,x);
else
std::cout << query(1,l,r) << '
';
}
}
树状数组
#include<bits/stdc++.h>
const int maxn = 1001000;
typedef long long ll;
int n,q,a[maxn];
ll a1[maxn],a2[maxn];
inline void add(ll * x,int p,ll v){ for(;p < maxn;p += p & -p) x[p] += v; }
inline ll query(ll * x,int p,ll ans=0){ for(;p;p&=p-1) ans += x[p]; return ans; }
int main(){
std::ios::sync_with_stdio(false),std::cin.tie(0);
std::cin >> n >> q;
for(int i=1;i<=n;++i) std::cin >> a[i];
for(int i=n;i>=1;--i) a[i] -= a[i-1], add(a1,i,a[i]), add(a2,i,a[i] * ll(i));
for(int i=1,op,l,r,x;i<=q;++i){
std::cin >> op >> l >> r;
if(op == 1) std::cin >> x, add(a1,l,x), add(a2,l,x * ll(l)), add(a1,r + 1,-x), add(a2,r + 1,-x * ll(r + 1));
else std::cout << query(a1,r) * (r + 1) - query(a2,r) - query(a1,l - 1) * l + query(a2,l - 1) << '
';
}
}
网络流
最大流
#include<bits/stdc++.h>
const int maxn = 200100;
struct T {
int to, nxt, v;
} way[maxn << 4];
int h[maxn], head[maxn], num = 1;
inline void adde(int x,int y,int v) {
way[++num] = {y, h[x], v}, h[x] = num;
way[++num] = {x, h[y], 0}, h[y] = num;
}
int dis[maxn];
inline bool bfs(int s,int t) {
std::queue<int> q;
for(int i = s;i <= t;++i) dis[i] = - 1, head[i] = h[i];
for(q.push(s), dis[s] = 0;!q.empty();) {
int t = q.front(); q.pop();
for(int i = h[t];i;i = way[i].nxt) if(way[i].v && dis[way[i].to] < 0)
dis[way[i].to] = dis[t] + 1, q.push(way[i].to);
}
return dis[t] >= 0;
}
inline int dfs(int s,int t,int lim) {
if(s == t || !lim) return lim;
int ans = 0, mn;
for(int & i = head[s];i;i = way[i].nxt)
if(dis[way[i].to] == dis[s] + 1 && (mn = dfs(way[i].to, t, std::min(lim, way[i].v)))) {
way[i].v -= mn;
way[i ^ 1].v += mn;
ans += mn; lim -= mn;
if(!lim) break;
}
return ans;
}
inline int dinic(int s,int t) {
int ans = 0;
for(;bfs(s,t);) ans += dfs(s,t,1e9);
return ans;
}
int main() {}
费用流
#include<bits/stdc++.h>
#include<bits/extc++.h>
typedef long long ll;
const int maxn = 100100;
const int dijkstra_tag = 114514;
const int bellmanford_tag = 1919810;
template <const int Tag = dijkstra_tag, const int node_cnt = 100000, const int edge_cnt = 1000000>
struct Graph {
static const int maxn = node_cnt + 10;
struct edge {
int to, nxt, v, f;
} way[(edge_cnt + 100) << 1];
int h[node_cnt], H[node_cnt], num, minidx, maxidx;
inline Graph() {
num = 1;
minidx = 1e9;
maxidx = 0;
}
inline void update(int x) {
if(x < minidx) minidx = x;
if(x > maxidx) maxidx = x;
}
inline void link(int x, int y, int v, int f) {
update(x), update(y);
way[++num] = {y, h[x], v, f}, h[x] = num;
way[++num] = {x, h[y], 0, -f}, h[y] = num;
}
typedef long long ll;
static const ll inf = 1e18;
ll dis[maxn], d[maxn];
int vis[maxn];
inline ll calc(int x) {
return Tag == dijkstra_tag ? way[x].f + d[way[x ^ 1].to] - d[way[x].to] : way[x].f;
}
inline bool bellmanford(ll * dis, int s, int t) {
std::queue<int> q;
static int inq[maxn];
for(int i = minidx;i <= maxidx;++i) dis[i] = inf;
dis[s] = 0, q.push(s);
for(;q.size();) {
int x = q.front(); q.pop();
inq[x] = 0;
for(int i = h[x];i;i = way[i].nxt) if(way[i].v) {
if(dis[way[i].to] > dis[x] + way[i].f) {
dis[way[i].to] = dis[x] + way[i].f;
if(!inq[way[i].to]) {
q.push(way[i].to);
inq[way[i].to] = 0;
}
}
}
}
return dis[t] < inf;
}
inline bool dijkstra(int s, int t) {
typedef std::pair<ll, int> pr;
static int vis[maxn];
__gnu_pbds::priority_queue<pr, std::greater<pr>> q;
static __gnu_pbds::priority_queue<pr, std::greater<pr>>::point_iterator iter[maxn];
for(int i = minidx;i <= maxidx;++i) iter[i] = q.push(pr(dis[i] = inf, i)), vis[i] = 0;
q.modify(iter[s], pr(dis[s] = 0, s));
for(;q.size();) {
int x = q.top().second; q.pop();
if(vis[x]) continue;
vis[x] = 1;
for(int i = h[x];i;i = way[i].nxt) if(way[i].v) {
if(dis[way[i].to] > dis[x] + calc(i)) {
q.modify(iter[way[i].to], pr(dis[way[i].to] = dis[x] + calc(i), way[i].to));
}
}
}
return dis[t] < inf;
}
inline int dfs(int x, int t, int lim) {
if(x == t || !lim) return lim;
int ans = 0, mn;
vis[x] = 1;
for(int &i = H[x];i;i = way[i].nxt) {
if(!vis[way[i].to] && dis[way[i].to] == dis[x] + calc(i) && (mn = dfs(way[i].to, t, std::min(lim, way[i].v)))) {
ans += mn, lim -= mn;
way[i].v -= mn, way[i ^ 1].v += mn;
if(!lim) break;
}
}
vis[x] = 0;
return ans;
}
inline std::pair<ll, ll> flow(int s, int t) {
ll cost = 0, sum = 0;
if(dijkstra_tag == Tag) {
bellmanford(d, s, t);
for(;dijkstra(s, t);) {
for(int i = minidx;i <= maxidx;++i) H[i] = h[i];
int c = dfs(s, t, 1e9);
for(int i = minidx;i <= maxidx;++i) d[i] += dis[i];
sum += c, cost += c * d[t];
}
} else {
for(;bellmanford(dis, s, t);) {
for(int i = minidx;i <= maxidx;++i) H[i] = h[i];
int c = dfs(s, t, 1e9);
sum += c;
cost += c * dis[t];
}
}
return {sum, cost};
}
};
Graph<> G;
int n, m, s, t;
int main() {
using std::cin;
using std::cout;
std::ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m >> s >> t;
for(int i = 1, u, v, w, f;i <= m;++i) {
cin >> u >> v >> w >> f;
G.link(u, v, w, f);
}
auto res = G.flow(s, t);
cout << res.first << ' ' << res.second << '
';
}
图论
最近公共祖先
#define _[1<<21]
#define Q scanf("%d%d"
#define M(x,y)D[x]<D[y]?x:y
i,x,j,D _,d _,s[20]_,T,h _,O _,N _,I;S(x,f,i){for(d[x]=++T,D[x]=D[f]+1,i=h[x];i;i=N[i])O[i]==f?:S(O[i],T[*s]=x);}A(x,j){N[++I]=h[x],O[h[x]=I]=j;}main(q){for(Q,d,&q);--*d;A(j,x))Q,&x,&j),A(x,j);for(S(1,0);x=i<19;++i)for(;s[i+1][x]=M(s[i][x],s[i][x+(1<<i)]);++x);for(;q--;printf("%d ",x^i?M(s[I][x],s[I][i-(1<<I)]):j))Q,&x,&j),x=d[x],i=d[j],x>i?x^=i^=x^=i:0,I=log2(i-x);}