#include
#include
#include
#include
#include
#include
#include
using namespace std;
int tree[1005 * 4], a[1005];
int lazy[1005 * 4];
//初始化线段树:当前处理p号,对应空间为[l,r]空间
void build(int p, int l, int r)
{
if (l == r)//到达叶子节点,直接赋值
{
tree[p] = a[l];//a中存储数据
return;
}
int mid = (l + r) / 2;
build(p * 2, l, mid);//递归构造左子树
build(p * 2 + 1, mid + 1, r);//递归构造右子树
tree[p] = tree[p * 2] + tree[p * 2 + 1];//合并左右子树,这里的合并逻辑是相加
}
//将lazy-tag向下传递一层
void push_down(int p, int l, int r)
{
int mid = (l + r) / 2;
lazy[p * 2] += lazy[p];
lazy[p * 2 + 1] += lazy[p];
tree[p * 2] += lazy[p] * (mid - l + 1);
tree[p * 2 + 1] += lazy[p] * (r - mid);
lazy[p] = 0;
}
//区间查找:当前节点p点,对应空间[l,r];查询[x,y]区间和
int find_interzone(int p, int l, int r, int x, int y)
{
int mid = (l + r) / 2;
int ans = 0;
if (r < x || l > y) //没有交集,返回0
return 0;
if (x <= l && y >= r)//[x,y]将[l,r]完全包含,返回区间值
return tree[p];
push_down(p, l, r); //如果使用lazy-tag需要加上这个
if (x <= mid)//左儿子和这个区间有交集,搜索左儿子
ans += find_interzone(p * 2, l, mid, x, y);
if (y > mid)//右儿子和这个区间有交集,搜索右儿子
ans += find_interzone(p * 2 + 1, mid + 1, r, x, y);
return ans;
}
//单点更新:当前节点p点,对应空间[l,r];将第key号点的值改为value
void update_dot(int p, int l, int r, int key, int value)
{
if (l == r)//在叶子节点中找到key点
{
tree[p] = value;
return;
}
int mid = (l + r) / 2;
if (key <= mid) //若key在左子树,递归查找
update_dot(p * 2, l, mid, key, value);
if (key > mid)//若key在右子树,递归查找
update_dot(p * 2 + 1, mid + 1, r, key, value);
tree[p] = tree[p * 2] + tree[p * 2 + 1];//回溯时修改每个节点的值
}
//区间更新:当前节点p,区间为[l,r],目标区间[x,y],操作是每个值加k
void update_interzone(int p, int l, int r, int x, int y, int k)
{
if (l > y || r < x)//[l,r]和[x,y]无交集,剪枝
return;
else if (l >= x && r <= y)//[l,r]被[x,y]完全包含
{
tree[p] += (r - l + 1) * k;//暂时不下放,节点p得到其子树的所有k
if (r > l) lazy[p] += k; //如果不是叶子节点,lazy-tag更新
}
else //[l,r]与[x,y]有交集
{
push_down(p, l, r);//需要操作子树,赶紧下放k
int mid = (l + r) / 2;
if(x<=mid) update_interzone(p * 2, l, mid, x, y, k);
if(y>mid) update_interzone(p * 2 + 1, mid + 1, r, x, y, k);
tree[p] = tree[p * 2] + tree[p * 2 + 1];//回溯时更新当前节点
}
}
//单点查询:当前节点p,区间为[l,r],目标点key
int find_dot(int p, int l, int r, int key)
{
if (l == r)
return tree[p];
push_down(p, l, r);
int mid = (l + r) / 2;
if (key <= mid)
find_dot(p * 2, l, mid, key);
else if (key > mid)
find_dot(p * 2 + 1, mid + 1, r, key);
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
build(1, 1, n);
for (int i = 0; i < m; i++)
{
int type; cin >> type;
if (type == 1)
{
int x, k;
cin >> x >> k;
update_dot(1, 1, n, x, k);
}
else
{
int x;
cin >> x;
printf("%d\n", find_dot(1, 1, n, x));
}
}
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int tree[2000005] = { 0 };
//最低位“1”的所在位置
int lowbit(int x)
{
return x & (-x);
}
//前缀和:求前n项和
long long sums(int n)
{
long long ans = 0;
for (int pos = n; pos > 0; pos -= lowbit(pos))
{
ans += tree[pos];
}
return ans;
}
//单点修改:将i号位置的元素加上k,树状数组的长度为len
void update(int i, int k, int len)
{
for (int pos = i; pos <= len; pos += lowbit(pos))
{
tree[pos] += k;
}
}
//区间查询:[l,r]范围的和
long long query(int l, int r)
{
return sums(r) - sums(l - 1);
}
int tree2[1005][1005];
//二维树状数组单点修改:[x,y]位置上的数加上data,数组大小为n*m
void update_2(int x, int y, int data, int n, int m)
{
for (int i = x; i <= n; x += lowbit(i))
{
for (int j = y; j <= m; j += lowbit(j))
{
tree2[i][j] += data;
}
}
}
//二维树状数组单点查询:返回tree2[0-x][0-y]之和,数组大小为n*m
int query_2(int x, int y, int n, int m)
{
int ans = 0;
for (int i = x; x > 0; x -= lowbit(i))
{
for (int j = y; j > 0; j -= lowbit(j))
{
ans += tree2[i][j];
}
}
return ans;
}
int main()
{
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int temp; cin >> temp;
update(i, temp, n);
}
for (int i = 1; i <= m; i++)
{
int tag; cin >> tag;
if (tag == 1)
{
int x, k; cin >> x >> k;
update(x, k, n);
}
if (tag == 2)
{
int x, y; cin >> x >> y;
cout << query(x, y) << endl;
}
}
}
#include
#include
#include
#include
#include
#include
#include
#define MAXN 201
#define inf 1<<30
using namespace std;
//Ford-Fulkerson算法
int cap[MAXN][MAXN];
int used[MAXN];
int v_num, e_num;
int dfs(int s, int t, int f)
{
if (s == t) return f; //到达终点,返回增广路径的流量
for (int i = 1; i <= v_num; i++)//遍历所有点
{
if (!used[i] && cap[s][i] > 0)//i点没有被二次使用 and s到i之间有路径
{
used[i] = 1;
int delta = dfs(i, t, min(f, cap[s][i]));//从i出发去寻找汇点
if (delta > 0) //如果找到路径,回溯时对路径进行修改
{
cap[s][i] -= delta; //正向路径减
cap[i][s] += delta; //反向路径加
return delta;
}
}
}
return 0;
}
int maxflow(int src, int des)
{
int f = 0, d = 0;
while (1)
{
memset(used, 0, sizeof(used));
used[1] = 1; //源点被使用
if (!(d = dfs(src, des, inf)))//没有增广路径了
return f;
f += d; //找到一条路,流量增加
}
}
int main()
{
int from, to, len;
while (scanf("%d%d", &e_num, &v_num) != EOF)
{
memset(cap, 0, sizeof(cap));
for (int i = 0; i < e_num; i++)
{
scanf("%d%d%d", &from, &to, &len);
cap[from][to] += len;
}
printf("%d\n", maxflow(1, v_num));
}
return 0;
}