标签:main tar ++ 大小 ems typedef type empty one
http://www.gdutcode.sinaapp.com/problem.php?cid=1049&pid=4
考虑下这个列子吧
2 4 1 3 5
和
2 4 1 5 3
首先它的数字不是1--n的,而且可能重复。
那么就离散化吧。把他们离散到1--n中。注意,如果数字是2、1、5、4、2
那么离散后的结果是2、1、5、4、3,总是要把她们离散到1---n
至于怎么离散,如果离散成2、1、5、4、2很容易,就是排序 + lowerbound
那么用book[val]表示这个数字出现了多少次,加上权值就可以了。
至于为什么我要离散成这样。就是因为其实这题每次都是要把最小的数字归位。
比如样例1,一开始我肯定是要让最小的那个数字,就是1,归位的吧,所以区间数字的数量最小都是3.
然后归位的时候发现途中有一个4,所以区间数字的数量要更改为4.(如果a[4]是5,那么就要变成5)
然后就在剩下的数字中,(现在只身下5)去找一个最小的数字归位。
其实就是模拟题,只不过每次必须的任务是把最小的数字归位。
离散成这样的目的是相对大小很明显,知道需要比较到那一位数字。
复杂度是O(nlogn)的
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 100000 + 20; int b[maxn]; int a[maxn]; int book[maxn]; bool vis[maxn]; struct node { int val, pos; bool operator < (const struct node & rhs) const { if (val != rhs.val) return val > rhs.val; else return pos > rhs.pos; } }; priority_queue<struct node>que; void work() { while (!que.empty()) que.pop(); memset(book, 0, sizeof book); int n; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &b[i]); a[i] = b[i]; } sort(b + 1, b + 1 + n); for (int i = 1; i <= n; ++i) { a[i] = lower_bound(b + 1, b + 1 + n, a[i]) - b; book[a[i]]++; a[i] += book[a[i]] - 1; } // for (int i = 1; i <= n; ++i) { // printf("%d ", a[i]); // } // printf("\n"); memset(vis, false, sizeof vis); for (int i = 1; i <= n; ++i) { struct node t; t.pos = i; t.val = a[i]; que.push(t); assert(vis[a[i]] == false); vis[a[i]] = true; } int ans = 0; int lef = -inf; int be = 1; while (!que.empty()) { struct node t = que.top(); que.pop(); if (t.pos <= lef) continue; lef = t.pos; int mx = -inf; while (true) { int tmx = mx; for (int i = be; i <= lef; ++i) { mx = max(a[i], mx); } if (tmx == mx) { be = mx + 1; lef = mx; break; } be = lef + 1; lef = mx; } ans++; } cout << ans << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif int t; scanf("%d", &t); while (t--) { work(); if (t) printf("\n"); } return 0; }
标签:main tar ++ 大小 ems typedef type empty one
原文地址:http://www.cnblogs.com/liuweimingcprogram/p/6131135.html