/* 这个题目对于线段树时间卡的很紧,所以才迫不得已学习树状数组 */ #include <iostream> #include <cstdio> #include <cstring> #define lowbit(x) (x & (-x)) // 具体怎么实现我也不知道 using namespace std; const int N = 10005; const int M = 3000005; int tree[N]; 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; }