所谓的日常 #9 - 除暴徒呂布助司徒 犯長安李倔聽賈詡
div.2
嗯,n * n的运行时间是不可以通过的...
事实上我们要对每个i,求出一个标号大于i且值小于A[i]的最大数,以及一个标号大于i且值大于A[i]的最小数。
那么将(A[i],i)这个二元组排序后得到数组B,然后维护一个标号单调递减的栈 来解决上面的两个问题。时间复杂度O(nlogn) (排序的复杂度)。
(>_<...嗯,这个题确实挂难了...起因是我把min看成了max,然后认为可以给大家做...不过还是有人通过了这个题好感动...恭喜@陈子民 同学 :)
用std::set也可以很方便的通过这个题,不过需要更多的C++知识啦,这里先不实现了。
#include <stdio.h> #include <algorithm> const int N = 100000 + 5; int n,A[N]; std::pair<int,int> B[N]; int stack[N],top; int answer[N]; void solve() { top = 0; for (int i = 0; i < n; ++ i) { int id = B[i].second; while (top > 0 && stack[top - 1] < id) -- top; if (top > 0) { answer[id] = std::min(answer[id],std::abs(A[stack[top - 1]] - A[id])); } stack[top++] = id; } } long long work() { for (int i = 0; i < n; ++ i) { B[i] = std::make_pair(A[i],i); } std::sort(B,B + n); for (int i = 0; i < n; ++ i) { answer[i] = (int)1e7; } answer[n - 1] = A[n - 1]; solve(); std::reverse(B,B + n); solve(); long long ret = 0; for (int i = 0; i < n; ++ i) { ret += answer[i]; } return ret; } int main() { while (scanf("%d",&n) == 1) { for (int i = 0; i < n; ++ i) { scanf("%d",A + i); } printf("%I64d\n",work()); } }
div.1
去吧STL...
拎着一个set,一个map,以及一个queue,再加一个树状数组,就可以ac这个题了。时间复杂度(nlogn)。由于set/map的巨大常数,跑了2.7s。
STL的话,在这里可以看 link
1 #include <stdio.h> 2 #include <string.h> 3 #include <map> 4 #include <set> 5 #include <queue> 6 #include <algorithm> 7 8 const int N = 100000 + 5; 9 int n; 10 std::map<int,int> map; 11 std::set<std::pair<int,int> > set; 12 std::queue<int> que; 13 int A[N],B[N]; 14 15 struct Fenwick { 16 int C[N]; 17 18 void clear() { 19 std::fill(C,C + n,0); 20 } 21 22 int modify(int p,int dt) { 23 for (int i = p; i < n; i += ~i & i + 1) C[i] += dt; 24 } 25 26 int query(int p) { 27 int ret = 0; 28 for (int i = p; i >= 0; i -= ~i & i + 1) ret += C[i]; 29 return ret; 30 } 31 } bit; 32 33 int main() { 34 while (scanf("%d",&n) == 1) { 35 bit.clear(); 36 map.clear(); 37 set.clear(); 38 while (!que.empty()) que.pop(); 39 40 for (int i = 0; i < n; ++ i) { 41 char str[13]; 42 scanf("%s",str); 43 if (strcmp(str,"add") == 0) { 44 int a,b; 45 scanf("%d%d",&a,&b); 46 A[i] = a; 47 B[i] = b; 48 map[a] = i; 49 set.insert(std::make_pair(b,i)); 50 que.push(i); 51 bit.modify(i,1); 52 } else if (strcmp(str,"pop") == 0) { 53 while (!que.empty() && map.find(A[que.front()]) == map.end()) que.pop(); 54 if (!que.empty()) { 55 int id = que.front(); que.pop(); 56 map.erase(A[id]); 57 set.erase(std::make_pair(B[id],id)); 58 bit.modify(id,-1); 59 } 60 } else if (strcmp(str,"leave") == 0) { 61 if (!set.empty()) { 62 int id = set.begin()->second; 63 set.erase(set.begin()); 64 bit.modify(id,-1); 65 map.erase(A[id]); 66 } 67 } else { 68 int x,y; 69 scanf("%d%d",&x,&y); 70 if (map.find(x) != map.end()) { 71 int id = map[x]; 72 int cnt = bit.query(id - 1); 73 printf("%d\n",cnt); 74 if (cnt > y) { 75 bit.modify(id,-1); 76 map.erase(A[id]); 77 set.erase(std::make_pair(B[id],id)); 78 } 79 } 80 } 81 } 82 } 83 }