您的位置:首页 > 理论基础 > 计算机网络

http://acm.hdu.edu.cn/showproblem.php?pid=2688 数状数组 线段树

2010-08-27 19:00 375 查看
/*
这个题目对于线段树时间卡的很紧,所以才迫不得已学习树状数组
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#define lowbit(x) (x & (-x))  // 具体怎么实现我也不知道
using namespace std;
const int N = 10005;
const int M = 3000005;
int tree
;
int df[M];
int Query(int x) { // 求 1 -- x 的区间的和
int sum = 0;
while (x > 0) {
sum += tree[x];
x -= lowbit(x);
}
return sum;
}
void Add(int a, int b) { //在位置a 改变b
while (a <= N - 1) {
tree[a] += b;
a += lowbit(a);
}
}
bool scan_ud(int &num) { // 传说中的外挂
char in;
in = getchar();
if (in == EOF)
return false;
while (in < '0' || in > '9')
in = getchar();
num = in - '0';
while (in = getchar(), in >= '0' && in <= '9') {
num *= 10, num += in - '0';
}
return true;
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
memset(tree, 0, sizeof(tree));
__int64 sum = 0;
for (int i = 0; i < n; i++) {
scan_ud(df[i]);
int num = Query(df[i] - 1);
sum += num;
Add(df[i], 1);
}
int m;
scanf("%d", &m);
char str[2];
int s, e;
while (m--) {
scanf("%s", str);
if (str[0] == 'Q') {
printf("%I64d/n", sum); // 这里是致命的错误,很容易判断有数据超int的
} else {
scan_ud(s);
scan_ud(e);
int temp = df[s];
int cou1 = 0;
int cou2 = 0;
for (int i = s + 1; i <= e; i++) {
if (df[i] > temp)
cou1++;
if (df[i] < temp)
cou2++;
df[i - 1] = df[i];
}
df[e] = temp;
sum = sum - cou1 + cou2;// 区间维护
}
}
}
}
 

 

/*
这个题目对时间卡的很紧。 开了外挂,线段树才勉强过了
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL(x) ((x) << 1)
#define RR(x) ((x) << 1 | 1)
using namespace std;
const int N = 10005;
const int M = 3000005;
struct Seg_tree {
int l, r; //sum;
int num;
int mid() {
return (l + r) >> 1;
}
} tree[4 * N];
int df[M];
inline bool scan_ud(int &num) {
char in;
in = getchar();
if (in == EOF)
return false;
while (in < '0' || in > '9')
in = getchar();
num = in - '0';
while (in = getchar(), in >= '0' && in <= '9') {
num *= 10, num += in - '0';
}
return true;
}
inline void Build(int l, int r, int node) {
tree[node].l = l;
tree[node].r = r;
tree[node].num = 0;
if (l == r)
return;
//int mid = (l + r) >> 1;
int mid = tree[node].mid();
Build(l, mid, LL(node));
Build(mid + 1, r, RR(node));
}
void Update(int dx, int node) {
tree[node].num++;
if (tree[node].l == tree[node].r) {
//tree[node].num++;
return;
}
int mid = tree[node].mid();
if (dx <= mid)
Update(dx, LL(node));
else
Update(dx, RR(node));
//tree[node].num = tree[LL(node)].num + tree[RR(node)].num;
}
inline int Query(int l, int r, int node) {
if (l <= tree[node].l && tree[node].r <= r) {
return tree[node].num;
}
int mid = tree[node].mid();
if (r <= mid) {
return Query(l, r, LL(node));
} else if (l > mid) {
return Query(l, r, RR(node));
} else {
return Query(l, mid, LL(node)) + Query(mid + 1, r, RR(node));
}
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
Build(1, N - 4, 1);
__int64 sum = 0;
for (int i = 0; i < n; i++) {
//scanf("%d", &df[i]);
scan_ud(df[i]);
if (df[i] != 1) {
int num = Query(1, df[i] - 1, 1);
sum += num;
}
Update(df[i], 1);
}
int m;
char str[2];
int s, e;
scanf("%d", &m);
//printf("%d/n", m);
while (m--) {
scanf("%s", str);
//printf("%s/n", str);
if (str[0] == 'Q') {
printf("%I64d/n", sum);
} else {
//scanf("%d %d", &s, &e);
scan_ud(s);
scan_ud(e);
int cou1 = 0;
int cou2 = 0;
/*
if(s > e){
int tt = s;
s = e;
e = tt;
}
*/
if(s >= e)
continue;
int tmp = df[s];
for (int i = s + 1; i <= e; i++) {
if (df[i] > tmp)
cou1++;
if (df[i] < tmp)
cou2++;
df[i - 1] = df[i];
}
df[e] = tmp;
//for (int i = 0; i < n; i++) {
//	printf("%d ", df[i]);
//}
//puts("");
//printf("cou1 :: %d cou2 :: %d/n", cou1, cou2);
sum = sum - cou1 + cou2;
}
}
}
return 0;
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tree query build struct