1、团队程序设计天梯赛-练习集-L3-002 堆栈
解题思路:
维护区间内点的个数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
#define DEBUG printf("debug\n")
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
char cmd[20];
int N;
stack<int> Stack;
struct SegTree {
int Left, Right;
int sum;
};
SegTree Tree[maxn*4];
void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
scanf("%d", &N);
Build(1, maxn, 1);
int t;
while (N--) {
scanf("%s", cmd);
if (strcmp(cmd, "Push") == 0) {
scanf("%d", &t);
Stack.push(t);
Update(t, 1, 1);
} else if (strcmp("Pop", cmd) == 0) {
if (!Stack.empty()) {
printf("%d\n", Stack.top());
Update(Stack.top(), -1, 1);
Stack.pop();
} else {
printf("Invalid\n");
}
} else {
int Count = Stack.size();
if (Count == 0) {
printf("Invalid\n");
} else {
if (Count & 1) {
++Count;
}
printf("%d\n", Query(Count>>1, 1));
}
}
}
return 0;
}
void Build(int low, int high, int index)
{
Tree[index].sum = 0;
Tree[index].Left = low;
Tree[index].Right = high;
if (low == high) {
return;
}
int mid = (low+high) / 2;
Build(low, mid, index*2);
Build(mid+1, high, index*2+1);
}
void Update(int target, int add, int index)
{
if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
Tree[index].sum += add;
return;
}
int mid = (Tree[index].Left + Tree[index].Right) / 2;
if (target <= mid) {
Update(target, add, index*2);
} else {
Update(target, add, index*2+1);
}
Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}
int Query(int target, int index)
{
if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
return Tree[index].Left;
}
if (Tree[index*2].sum >= target) {
return Query(target, index*2);
} else {
return Query(target-Tree[index*2].sum, index*2+1);
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
char cmd[20];
int N;
int tree[maxn];
stack<int> Stack;
int lowbit(int x);
void Update(int x, int add);
int Query(int x);
int PeekMedian(int low, int high, int x);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif // __AiR_H
scanf("%d", &N);
memset(tree, 0, sizeof(tree));
int t;
while (N--) {
scanf("%s", cmd);
if (strcmp(cmd, "Push") == 0) {
scanf("%d", &t);
Stack.push(t);
Update(t, 1);
} else if (strcmp("Pop", cmd) == 0) {
if (!Stack.empty()) {
printf("%d\n", Stack.top());
Update(Stack.top(), -1);
Stack.pop();
} else {
printf("Invalid\n");
}
} else {
int Count = Stack.size();
if (Count == 0) {
printf("Invalid\n");
} else {
if (Count & 1) {
++Count;
}
printf("%d\n", PeekMedian(1, maxn, Count>>1));
}
}
}
return 0;
}
int lowbit(int x)
{
return (x&(-x));
}
void Update(int x, int add)
{
while (x < maxn) {
tree[x] += add;
x += lowbit(x);
}
}
int Query(int x)
{
int ret = 0;
while (x > 0) {
ret += tree[x];
x -= lowbit(x);
}
return ret;
}
int PeekMedian(int low, int high, int x)
{
if (low == high) {
return low;
}
int mid = (low + high) / 2;
int t = Query(mid) - Query(low-1);
if (t >= x) {
return PeekMedian(low, mid, x);
} else {
return PeekMedian(mid+1, high, x-t);
}
}
2、UESTC 1339 郭大侠与线上游戏
如果用线段树和树状数组做的话需要离散化一下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
map<int, int> Map;
int key[maxn];
struct SegTree {
int Left, Right;
int sum;
};
SegTree Tree[maxn*5];
void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif // __AiR_H
int n;
scanf("%d", &n);
Build(1, maxn, 1);
for (int i = 0; i < n; ++i) {
scanf("%d", &cmd[i][0]);
if (cmd[i][0] == 1) {
scanf("%d",&cmd[i][1]);
if (Map[cmd[i][1]] == 0) {
Map[cmd[i][1]] = 1;
}
}
}
map<int, int>::iterator itr;
int id = 1;
for (itr = Map.begin(); itr != Map.end(); ++itr) {
key[id] = itr->first;
itr->second = id++;
}
for (int i = 0; i < n; ++i) {
if (cmd[i][0] == 1) {
Q.push(Map[cmd[i][1]]);
Update(Map[cmd[i][1]], 1, 1);
} else if (cmd[i][0] == 2) {
Update(Q.front(), -1, 1);
Q.pop();
} else {
int Size = Q.size();
printf("%d\n", key[Query(Size/2+1, 1)]);
}
}
return 0;
}
void Build(int low, int high, int index)
{
Tree[index].sum = 0;
Tree[index].Left = low;
Tree[index].Right = high;
if (low == high) {
return;
}
int mid = (low+high) / 2;
Build(low, mid, index*2);
Build(mid+1, high, index*2+1);
}
void Update(int target, int add, int index)
{
if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
Tree[index].sum += add;
return;
}
int mid = (Tree[index].Left + Tree[index].Right) / 2;
if (target <= mid) {
Update(target, add, index*2);
} else {
Update(target, add, index*2+1);
}
Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}
int Query(int target, int index)
{
if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
return Tree[index].Left;
}
if (Tree[index*2].sum >= target) {
return Query(target, index*2);
} else {
return Query(target-Tree[index*2].sum, index*2+1);
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;
struct SegTree {
int Left, Right;
int sum;
};
SegTree Tree[maxn*4];
int GetId(int x);
void Build(int low, int high, int index);
void Update(int target, int add, int index);
int Query(int target, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif // __AiR_H
int n;
scanf("%d", &n);
Build(1, maxn, 1);
for (int i = 0; i < n; ++i) {
scanf("%d", &cmd[i][0]);
if (cmd[i][0] == 1) {
scanf("%d",&cmd[i][1]);
V.push_back(cmd[i][1]);
}
}
sort(V.begin(), V.end());
V.erase(unique(V.begin(), V.end()), V.end());
for (int i = 0; i < n; ++i) {
if (cmd[i][0] == 1) {
int t = GetId(cmd[i][1]);
Q.push(t);
Update(t, 1, 1);
} else if (cmd[i][0] == 2) {
Update(Q.front(), -1, 1);
Q.pop();
} else {
int Size = Q.size();
printf("%d\n", V[Query(Size/2+1, 1)-1]);
}
}
return 0;
}
int GetId(int x)
{
return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}
void Build(int low, int high, int index)
{
Tree[index].sum = 0;
Tree[index].Left = low;
Tree[index].Right = high;
if (low == high) {
return;
}
int mid = (low+high) / 2;
Build(low, mid, index*2);
Build(mid+1, high, index*2+1);
}
void Update(int target, int add, int index)
{
if (Tree[index].Left == Tree[index].Right && Tree[index].Left == target) {
Tree[index].sum += add;
return;
}
int mid = (Tree[index].Left + Tree[index].Right) / 2;
if (target <= mid) {
Update(target, add, index*2);
} else {
Update(target, add, index*2+1);
}
Tree[index].sum = Tree[index*2].sum + Tree[index*2+1].sum;
}
int Query(int target, int index)
{
if (Tree[index].Left == Tree[index].Right && target <= Tree[index].sum) {
return Tree[index].Left;
}
if (Tree[index*2].sum >= target) {
return Query(target, index*2);
} else {
return Query(target-Tree[index*2].sum, index*2+1);
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;
int Tree[maxn<<2];
int GetId(int x);
void Update(int low, int high, int target, int add, int index);
int Query(int low, int high, int target, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &cmd[i][0]);
if (cmd[i][0] == 1) {
scanf("%d",&cmd[i][1]);
V.push_back(cmd[i][1]);
}
}
sort(V.begin(), V.end());
V.erase(unique(V.begin(), V.end()), V.end());
for (int i = 0; i < n; ++i) {
if (cmd[i][0] == 1) {
int t = GetId(cmd[i][1]);
Q.push(t);
Update(1, maxn, t, 1, 1);
} else if (cmd[i][0] == 2) {
Update(1, maxn, Q.front(), -1, 1);
Q.pop();
} else {
int Size = Q.size();
printf("%d\n", V[Query(1, maxn, Size/2+1, 1)-1]);
}
}
return 0;
}
int GetId(int x)
{
return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}
void Update(int low, int high, int target, int add, int index)
{
Tree[index] += add;
if (low == high) {
return;
}
int mid = (low + high) / 2;
if (target <= mid) {
Update(low, mid, target, add, index*2);
} else {
Update(mid+1, high, target, add, index*2+1);
}
}
int Query(int low, int high, int target, int index)
{
if (low == high) {
return low;
}
int mid = (low + high) / 2;
if (Tree[index*2] >= target) {
return Query(low, mid, target, index*2);
} else {
return Query(mid+1, high, target-Tree[index*2], index*2+1);
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e6 + 10;
int cmd[maxn][2];
queue<int> Q;
vector<int> V;
int tree[maxn];
int GetId(int x);
int lowbit(int x);
void Update(int x, int add);
int Query(int x);
int PeekMedian(int low, int high, int x);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif // __AiR_H
int n;
memset(tree, 0, sizeof(tree));
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &cmd[i][0]);
if (cmd[i][0] == 1) {
scanf("%d",&cmd[i][1]);
V.push_back(cmd[i][1]);
}
}
sort(V.begin(), V.end());
V.erase(unique(V.begin(), V.end()), V.end());
for (int i = 0; i < n; ++i) {
if (cmd[i][0] == 1) {
int t = GetId(cmd[i][1]);
Q.push(t);
Update(t, 1);
} else if (cmd[i][0] == 2) {
Update(Q.front(), -1);
Q.pop();
} else {
int Size = Q.size();
printf("%d\n", V[PeekMedian(1, maxn, Size/2+1)-1]);
}
}
return 0;
}
int GetId(int x)
{
return (lower_bound(V.begin(), V.end(), x) - V.begin() + 1);
}
int lowbit(int x)
{
return (x & (-x));
}
void Update(int x, int add)
{
while (x < maxn) {
tree[x] += add;
x += lowbit(x);
}
}
int Query(int x)
{
int ret = 0;
while (x > 0) {
ret += tree[x];
x -= lowbit(x);
}
return ret;
}
int PeekMedian(int low, int high, int x)
{
if (low == high) {
return low;
}
int mid = (low + high) >> 1;
int t = Query(mid) - Query(low-1);
if (t >= x) {
return PeekMedian(low, mid, x);
} else {
return PeekMedian(mid+1, high, x-t);
}
}
3、HDU 5726 GCD
官方题解:
http://bestcoder.hdu.edu.cn/blog/2016-multi-university-training-contest-1-solutions-by-hit/
先%一下写标程的大牛,再贴标程
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#define dprint(expr) fprintf(stderr, #expr " = %d\n", expr)
#define MP make_pair
#define PB push_back
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-6;
const double PI = acos(-1.0);
vector <PII> gcd[N];
map <int, LL> Ans;
int n;
int num[N];
int main(void){
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T, Test = 0;
scanf("%d", &T);
while (T--) {
//cerr << T << endl;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
}
Ans.clear();
for (int k = 1; k <= n; ++k) {
int last = 0;
for (int i = 0; i < gcd[k - 1].size(); ++i) {
int u = gcd[k - 1][i].first, v = gcd[k - 1][i].second;
int g = __gcd(u, num[k]);
if (g == last) continue;
last = g;
gcd[k].PB(MP(g, v));
}
if (num[k] != last) {
gcd[k].PB(MP(num[k], k));
}
for (int i = 0; i < gcd[k].size(); ++i) {
Ans[gcd[k][i].first] += (i == gcd[k].size() - 1 ? k + 1 : gcd[k][i + 1].second) - gcd[k][i].second;
}
}
int Q;
scanf("%d", &Q);
printf("Case #%d:\n", ++Test);
while (Q--) {
int u, v, k;
scanf("%d%d", &u, &v);
for (k = 0; k < gcd[v].size(); ++k)
if (gcd[v][k].second > u)
break;
// for (int i = 0; i < gcd[v].size(); ++i) {
// printf("%d -> %d\n", i, gcd[v][i]);
// }
printf("%d %I64d\n", gcd[v][k - 1].first, Ans[gcd[v][k - 1].first]);
}
for (int i = 0; i <= n; ++i)
gcd[i].clear();
}
return 0;
}
对着标程和题解一下午一晚上,加上在纸上乱画、输出中间结果等等尝试,终于看懂了标程,然后照敲了一遍...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
vector<pair<int, int> > gcd[maxn];
map<int, ll> ans;
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
int Case = 0;
while (T--) {
printf("Case #%d:\n", ++Case);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i= 0; i <= n; ++i) {
gcd[i].clear();
}
ans.clear();
for (int i = 1; i <= n; ++i) {
int last = 0;
for (int j = 0; j < (int)gcd[i - 1].size(); ++j) {
int t1 = gcd[i-1][j].first, t2 = gcd[i-1][j].second;
int g = __gcd(t1, a[i]);
if (g != last) {
last = g;
gcd[i].push_back(make_pair(g, t2));
}
}
if (a[i] != last) {
gcd[i].push_back(make_pair(a[i], i));
}
for (int j = 0; j < (int)gcd[i].size(); ++j) {
if (j == (int)gcd[i].size() - 1) {
ans[gcd[i][j].first] += i+1 - gcd[i][j].second;
} else {
ans[gcd[i][j].first] += gcd[i][j+1].second - gcd[i][j].second;
}
}
}
int Q;
scanf("%d", &Q);
while (Q--) {
int l, r;
scanf("%d%d", &l, &r);
int Count = 0;
while (Count < (int)gcd[r].size()) {
if (gcd[r][Count].second > l) {
break;
}
++Count;
}
printf("%d %I64d\n", gcd[r][Count-1].first, ans[gcd[r][Count-1].first]);
}
}
return 0;
}
参考: http://blog.csdn.net/queuelovestack/article/details/51958142
发现了一种预处理比较好理解的做法,预处理出来所有 gcd 值在区间出现的次数,然后查询用线段树做
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
struct SegTree {
int Left, Right;
int gcd;
};
SegTree Tree[maxn*4];
map<int, ll> ans, Map, Map_t;
void Build(int low, int high, int index);
int Query(int l, int r, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
int Case = 0;
while (T--) {
ans.clear(), Map.clear(), Map_t.clear();
printf("Case #%d:\n", ++Case);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
Build(1, n, 1);
map<int, ll>::iterator itr;
for (int i = 1; i <= n; ++i) {
++ans[a[i]];
++Map[a[i]];
for (itr = Map_t.begin(); itr != Map_t.end(); ++itr) {
int g = __gcd(itr->first, a[i]);
ans[g] += itr->second;
Map[g] += itr->second;
}
Map_t.clear();
for (itr = Map.begin(); itr != Map.end(); ++itr) {
Map_t[itr->first] = itr->second;
}
Map.clear();
}
int Q;
scanf("%d", &Q);
while (Q--) {
int l, r;
scanf("%d%d", &l, &r);
int g = Query(l, r, 1);
printf("%d %I64d\n", g, ans[g]);
}
}
return 0;
}
void Build(int low, int high, int index)
{
Tree[index].Left = low, Tree[index].Right = high;
if (low == high) {
Tree[index].gcd = a[low];
return;
}
int mid = (low + high) >> 1;
Build(low, mid, index*2);
Build(mid+1, high, index*2+1);
Tree[index].gcd = __gcd(Tree[index*2].gcd, Tree[index*2+1].gcd);
}
int Query(int l, int r, int index)
{
if (Tree[index].Left == l && Tree[index].Right == r) {
return Tree[index].gcd;
}
int mid = (Tree[index].Left + Tree[index].Right) >> 1;
if (r <= mid) {
return Query(l, r, index*2);
} else if (mid < l) {
return Query(l, r, index*2+1);
} else {
return __gcd(Query(l, mid, index*2), Query(mid+1, r, index*2+1));
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int a[maxn];
int n;
int Tree[maxn*4];
map<int, ll> ans, Map, Map_t;
void Build(int low, int high, int index);
int Query(int low, int high, int l, int r, int index);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
int Case = 0;
while (T--) {
ans.clear(), Map.clear(), Map_t.clear();
printf("Case #%d:\n", ++Case);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
Build(1, n, 1);
map<int, ll>::iterator itr;
for (int i = 1; i <= n; ++i) {
++ans[a[i]];
++Map[a[i]];
for (itr = Map_t.begin(); itr != Map_t.end(); ++itr) {
int g = __gcd(itr->first, a[i]);
ans[g] += itr->second;
Map[g] += itr->second;
}
Map_t.clear();
for (itr = Map.begin(); itr != Map.end(); ++itr) {
Map_t[itr->first] = itr->second;
}
Map.clear();
}
int Q;
scanf("%d", &Q);
while (Q--) {
int l, r;
scanf("%d%d", &l, &r);
int g = Query(1, n, l, r, 1);
printf("%d %I64d\n", g, ans[g]);
}
}
return 0;
}
void Build(int low, int high, int index)
{
if (low == high) {
Tree[index] = a[low];
return;
}
int mid = (low + high) >> 1;
Build(low, mid, index*2);
Build(mid+1, high, index*2+1);
Tree[index] = __gcd(Tree[index*2], Tree[index*2+1]);
}
int Query(int low, int high, int l, int r, int index)
{
if (low == l && high == r) {
return Tree[index];
}
int mid = (low + high) >> 1;
if (r <= mid) {
return Query(low, mid, l, r, index*2);
} else if (mid < l) {
return Query(mid+1, high, l, r, index*2+1);
} else {
return __gcd(Query(low, mid, l, mid, index*2), Query(mid+1, high, mid+1, r, index*2+1));
}
}
4、HDU 5775 Bubble Sort
解题思路:
找到每个值后面比它小的值的个数,加上当前位置为这个值的最右边的位置
最后才想通,赶快树状数组敲了一发。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e5 + 10;
int y[maxn];
int c[maxn];
int Left[maxn], Right[maxn];
int n;
int lowbit(int x);
void Update(int x);
int Query(int x);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
int T;
scanf("%d", &T);
int Case = 0;
while (T--) {
memset(c, 0, sizeof(c));
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &y[i]);
Left[y[i]] = Right[y[i]] = i;
if (y[i] < Left[y[i]]) {
Left[y[i]] = y[i];
} else if (y[i] > Right[i]) {
Right[y[i]] = y[i];
}
}
for (int i = n; i >= 1; --i) {
int t = Query(y[i]);
if (i+t > Right[y[i]]) {
Right[y[i]] = i+t;
}
Update(y[i]);
}
printf("Case #%d: %d", ++Case, abs(Left[1] - Right[1]));
for (int i = 2; i <= n; ++i) {
printf(" %d", abs(Left[i] - Right[i]));
}
printf("\n");
}
return 0;
}
int lowbit(int x)
{
return (x & (-x));
}
void Update(int x)
{
while (x < maxn) {
c[x] += 1;
x += lowbit(x);
}
}
int Query(int x)
{
int ret = 0;
while (x) {
ret += c[x];
x -= lowbit(x);
}
return ret;
}
5、HDU 5122 K.Bro Sorting
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 3e6 + 10;
int T, N, ans = 0, Case = 0;
int a[maxn], c[maxn];
int lowbit(int x);
void update(int x);
int query(int x);
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
scanf("%d", &T);
while (T--) {
scanf("%d", &N);
memset(c, 0, sizeof(c));
for (int i = 1; i <= N; ++i) {
scanf("%d", &a[i]);
}
ans = 0;
for (int i = N; i > 0; --i) {
if (query(a[i])) {
++ans;
}
update(a[i]);
}
printf("Case #%d: %d\n", ++Case, ans);
}
return 0;
}
int lowbit(int x)
{
return (x & (-x));
}
void update(int x)
{
while (x < maxn) {
++c[x], x += lowbit(x);
}
}
int query(int x)
{
int ret = 0;
while (x > 0) {
ret += c[x], x -= lowbit(x);
}
return ret;
}