POJ 3264 模板题目
#include<stdio.h>
#include<algorithm>
using namespace std;
const int INF = 1 << 30;
int minV = INF;
int maxV = -INF;
struct Node
{
int maxV;
int minV;
int L, R;
int mid()
{
return (L + R) / 2;
}
};
Node tree[800010];
void buildTree(int root, int L, int R)
{
tree[root].L = L;
tree[root].R = R;
tree[root].maxV = -INF;
tree[root].minV = INF;
if (L != R)
{
buildTree(2 * root + 1, L, (L + R) / 2);
buildTree(2 * root + 2, (L + R) / 2 + 1, R);
}
}
void insert(int root, int i, int v)
{
if (tree[root].L == tree[root].R)
{
tree[root].minV = tree[root].maxV=v;
return;
}
tree[root].minV = min(tree[root].minV, v);
tree[root].maxV = max(tree[root].maxV, v);
if (i <= tree[root].mid())
insert(2 * root + 1, i, v);
else
insert(2 * root + 2, i, v);
}
void query(int root, int s, int e)
{
if (tree[root].minV >= minV && tree[root].maxV <= maxV)
return;
if (tree[root].L == s && tree[root].R == e)
{
minV = min(minV, tree[root].minV);
maxV = max(maxV, tree[root].maxV);
return;
}
if (e <= tree[root].mid())
query(2 * root + 1, s, e);
else if (s>tree[root].mid())
query(2 * root + 2, s, e);
else
{
query(2 * root + 1, s, tree[root].mid());
query(2 * root + 2, tree[root].mid() + 1, e);
}
}
int main()
{
int n, q, h;
scanf("%d%d", &n, &q);
buildTree(0, 1, n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &h);
insert(0, i, h);
}
for (int i = 0; i<q; i++)
{
int s, e;
scanf("%d%d", &s, &e);
minV = INF;
maxV = -INF;
query(0, s, e);
printf("%d\n", maxV - minV);
}
}
POJ 3468 模板题2
#include<stdio.h>
#include<algorithm>
using namespace std;
struct CNode
{
int L, R;
CNode *left,* right;
long long nsum;
long long lnc;
int mid()
{
return (L + R) / 2;
}
};
CNode Tree[200010];
int nCount = 0;
void buildTree(CNode * pRoot, int L, int R)
{
pRoot->L = L;
pRoot->R = R;
pRoot->nsum = 0;
pRoot->lnc = 0;
if (L == R)
return;
nCount++;
pRoot->left = Tree + nCount;
nCount++;
pRoot->right = Tree + nCount;
buildTree(pRoot->left, L, (L + R) / 2);
buildTree(pRoot->right, (L + R) / 2 + 1, R);
}
void insert(CNode* pRoot, int i, int v)
{
if (pRoot->L == i && pRoot->R == i)
{
pRoot->nsum = v;
return;
}
pRoot->nsum += v;
if (i <= pRoot->mid())
insert(pRoot->left, i, v);
else
insert(pRoot->right, i, v);
}
void add(CNode * pRoot, int a, int b, long long c)
{
if (pRoot->L == a && pRoot->R == b)
{
pRoot->lnc += c;
return;
}
pRoot->nsum+=(b-a+1)*c;
if (b <= pRoot->mid())
add(pRoot->left, a, b, c);
else if (a>pRoot->mid())
add(pRoot->right, a, b, c);
else
{
add(pRoot->left, a, pRoot->mid(), c);
add(pRoot->right, pRoot->mid()+1, b, c);
}
}
long long querySum(CNode* pRoot, int a, int b)
{
if (pRoot->L == a && pRoot->R == b)
{
return pRoot->nsum + (pRoot->R - pRoot->L + 1)*pRoot->lnc;
}
pRoot->nsum += (pRoot->R - pRoot->L + 1)*pRoot->lnc;
add(pRoot->left, pRoot->L, pRoot->mid(), pRoot->lnc);
add(pRoot->right, pRoot->mid()+1, pRoot->R, pRoot->lnc);
pRoot->lnc = 0;
if (b <= pRoot->mid())
return querySum(pRoot->left, a, b);
else if (a>pRoot->mid())
return querySum(pRoot->right, a, b);
else
{
return querySum(pRoot->left, a, pRoot->mid()) + querySum(pRoot->right, pRoot->mid() + 1, b);
}
}
int main()
{
int n, q, a, b, c;
char cmd[10];
scanf("%d%d", &n, &q);
nCount = 0;
buildTree(Tree, 1, n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a);
insert(Tree, i, a);
}
for (int i = 0; i<q; i++)
{
scanf("%s", cmd);
if (cmd[0] == 'C')
{
scanf("%d%d%d", &a, &b, &c);
add(Tree, a, b, c);
}
else
{
scanf("%d%d", &a, &b);
printf("%lld\n", querySum(Tree, a, b));
}
}
}
POJ 2528 海报张贴
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct Node
{
int l, r;
bool iscovered;//Full coverage
int left, right;
int mid()
{
return (l + r) / 2;
}
};
Node tree[50000];
struct Poster
{
int l, r;
};
Poster poster[10010];
int sortArr[20020];
int hashArr[10000010];
int n;
int cnt;
void buildTree(int root, int a, int b)
{
tree[root].iscovered = false;
tree[root].l = a;
tree[root].r = b;
if (a == b)
return;
tree[root].left = 2 * root + 1;
tree[root].right = 2 * root + 2;
buildTree(tree[root].left, a, tree[root].mid());
buildTree(tree[root].right, tree[root].mid() + 1, b);
}
bool insert(int root, int a, int b)//1 ,wan quan fu gai
{
if (tree[root].iscovered == true)
return true;
if (tree[root].l == a && tree[root].r == b)
{
tree[root].iscovered = true;
return false;
}
bool result;
if (b <= tree[root].mid())
result = insert(tree[root].left, a, b);
else if (a>tree[root].mid())
result = insert(tree[root].right, a, b);
else
{
bool result1 = insert(tree[root].left, a, tree[root].mid());
bool result2 = insert(tree[root].right, tree[root].mid() + 1, b);
result = result1&&result2;
}
if (tree[tree[root].left].iscovered == true && tree[tree[root].right].iscovered == true)
tree[root].iscovered = true;
return result;
}
int main()
{
int c;
scanf("%d", &c);
while (c--)
{
scanf("%d", &n);
cnt = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d%d", &poster[i].l, &poster[i].r);
sortArr[cnt++] = poster[i].l;
sortArr[cnt++] = poster[i].r;
}
sort(sortArr, sortArr + cnt);
cnt = unique(sortArr, sortArr + cnt) - sortArr;
memset(hashArr, -1, sizeof(hashArr));
for (int i = 0; i<cnt; i++)
{
hashArr[sortArr[i]] = i;
}
buildTree(0, 0, cnt);
int ans = 0;
for (int i = n; i >= 1; i--)
{
if (!insert(0, hashArr[poster[i].l], hashArr[poster[i].r]))
ans++;
}
printf("%d\n", ans);
}
}
POJ 1151 矩形面积(区间两头的点)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
const int MAXN = 110;
map<double, int> yMap;
struct Node
{
double len;
int cover;
int l, r;
};
struct Line
{
double x, y1, y2;
bool isLeft;
bool operator<(const Line & rhs)const
{
return x<rhs.x;
}
};
Node tree[MAXN * 5];
Line lines[MAXN * 2];
int n, cnt;
double y[MAXN * 2];
void build(int root, int l, int r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].len = 0;
tree[root].cover = 0;
if (r > l + 1)
{
build(2 * root, l, (l + r) / 2);
build(2 * root + 1, (l + r) / 2, r);
}
}
void insert(int root, int l, int r)
{
if (tree[root].l == l && tree[root].r == r)
{
tree[root].cover++;
tree[root].len = y[r] - y[l];
return;
}
int mid = (tree[root].l + tree[root].r) / 2;
if (r <= mid)
insert(2 * root, l, r);
else if (l >= mid)
insert(2 * root + 1, l, r);
else
{
insert(2 * root, l, mid);
insert(2 * root + 1, mid, r);
}
if (tree[root].cover == 0)
{
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
}
}
void del(int root, int l, int r)
{
if (tree[root].l == l && tree[root].r == r)
{
tree[root].cover--;
if (tree[root].cover == 0)
{
if (tree[root].r - tree[root].l > 1)
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
else
tree[root].len = 0;
}
return;
}
else
{
int mid = (tree[root].l + tree[root].r) / 2;
if (r <= mid)
del(2 * root, l, r);
else if (l >= mid)
del(2 * root + 1, l, r);
else
{
del(2 * root, l, mid);
del(2 * root + 1, mid, r);
}
}
if (tree[root].cover == 0)
{
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
}
}
int main()
{
int t = 1;
while (true)
{
yMap.clear();
double x1, x2, y1, y2;
scanf("%d", &n);
if (n == 0)
return 0;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
lines[2 * i].x = x1;
lines[2 * i + 1].x = x2;
lines[2 * i].y1 = lines[2 * i + 1].y1 = y1;
lines[2 * i].y2 = lines[2 * i + 1].y2 = y2;
lines[2 * i].isLeft = true;
lines[2 * i + 1].isLeft = false;
y[2 * i] = y1;
y[2 * i + 1] = y2;
}
sort(y, y + 2 * n);
cnt = unique(y, y + 2 * n) - y;
for (int i = 0; i < cnt; i++)
yMap[y[i]] = i;
sort(lines, lines + 2 * n);
build(1, 0, cnt - 1);
double ans = 0;
for (int i = 0; i < 2 * n - 1; i++)
{
if (lines[i].isLeft)
insert(1, yMap[lines[i].y1], yMap[lines[i].y2]);
else
del(1, yMap[lines[i].y1], yMap[lines[i].y2]);
ans += tree[1].len*(lines[i + 1].x - lines[i].x);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", t++, ans);
}
}
POJ 1151 矩形面积(区间)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
const int MAXN = 110;
map<double, int> yMap;
struct Node
{
double len;
int cover;
int l, r;
};
struct Line
{
double x, y1, y2;
bool isLeft;
bool operator<(const Line & rhs)const
{
return x < rhs.x;
}
};
Node tree[MAXN * 5];
Line lines[MAXN * 2];
int n, cnt;
double y[MAXN * 2];
void build(int root, int l, int r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].len = 0;
tree[root].cover = 0;
if (r != l)
{
build(2 * root, l, (l + r) / 2);
build(2 * root + 1, (l + r) / 2 + 1, r);
}
}
void insert(int root, int l, int r)
{
if (tree[root].l == l && tree[root].r == r)
{
tree[root].cover++;
tree[root].len = y[r + 1] - y[l];
return;
}
int mid = (tree[root].l + tree[root].r) / 2;
if (r <= mid)
insert(2 * root, l, r);
else if (l >= mid+1)
insert(2 * root + 1, l, r);
else
{
insert(2 * root, l, mid);
insert(2 * root + 1, mid + 1, r);
}
if (tree[root].cover == 0)
{
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
}
}
void del(int root, int l, int r)
{
if (tree[root].l == l && tree[root].r == r)
{
tree[root].cover--;
if (tree[root].cover == 0)
{
if (tree[root].r != tree[root].l)
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
else
tree[root].len = 0;
}
return;
}
else
{
int mid = (tree[root].l + tree[root].r) / 2;
if (r <= mid)
del(2 * root, l, r);
else if (l >= mid+1)
del(2 * root + 1, l, r);
else
{
del(2 * root, l, mid);
del(2 * root + 1, mid + 1, r);
}
}
if (tree[root].cover == 0)
{
tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
}
}
int main()
{
int t = 1;
while (true)
{
yMap.clear();
double x1, x2, y1, y2;
scanf("%d", &n);
if (n == 0)
return 0;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
lines[2 * i].x = x1;
lines[2 * i + 1].x = x2;
lines[2 * i].y1 = lines[2 * i + 1].y1 = y1;
lines[2 * i].y2 = lines[2 * i + 1].y2 = y2;
lines[2 * i].isLeft = true;
lines[2 * i + 1].isLeft = false;
y[2 * i] = y1;
y[2 * i + 1] = y2;
}
sort(y, y + 2 * n);
cnt = unique(y, y + 2 * n) - y;
for (int i = 0; i < cnt; i++)
yMap[y[i]] = i;
sort(lines, lines + 2 * n);
build(1, 0, cnt - 1 - 1);
double ans = 0;
for (int i = 0; i < 2 * n - 1; i++)
{
if (lines[i].isLeft)
insert(1, yMap[lines[i].y1], yMap[lines[i].y2]-1);
else
del(1, yMap[lines[i].y1], yMap[lines[i].y2]-1);
ans += tree[1].len*(lines[i + 1].x - lines[i].x);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", t++, ans);
}
}
POJ 3321 苹果树 树状数组
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXN 100010
vector<vector<int> > graph(100010);
int start[MAXN];
int End[MAXN];
int c[MAXN * 2];
int n;
int ncount;
int lowBit[MAXN*2];
int hasApple[MAXN];
void dfs(int u)
{
start[u] = ++ncount;
for (int i = 0; i<graph[u].size(); i++)
{
dfs(graph[u][i]);
}
End[u] = ++ncount;
}
void modify(int num, int val)
{
while (num <= ncount)
{
c[num] += val;
num += lowBit[num];
}
}
int query(int num)
{
int sum = 0;
while (num>0)
{
sum += c[num];
num -= lowBit[num];
}
return sum;
}
int main()
{
scanf("%d", &n);
int u, v;
ncount = 0;
for (int i = 0; i<MAXN; i++)
hasApple[i] = 1;
for (int i = 0; i<n - 1; i++)
{
scanf("%d%d", &u, &v);
graph[u].push_back(v);
}
dfs(1);
for (int i = 0; i <= ncount; i++)
lowBit[i] = (i&(-i));
for (int i = 0; i <= ncount; i++)
c[i] = i - (i - lowBit[i]);
int m;
scanf("%d", &m);
char cmd[5];
int a;
for (int i = 0; i<m; i++)
{
scanf("%s%d", cmd, &a);
if (cmd[0] == 'C')
{
if (hasApple[a])
{
hasApple[a] = 0;
modify(start[a], -1);
modify(End[a], -1);
}
else
{
hasApple[a] = 1;
modify(start[a], 1);
modify(End[a], 1);
}
}
else
{
int t1 = query(start[a] - 1);
int t2 = query(End[a]);
printf("%d\n", (t2 - t1) / 2);
}
}
}