- #include <algorithm> 
-   
- #include <iterator> 
- #include <iostream> 
- using namespace std; 
-   
- template < 
-       typename MultiPassIOIterator 
-     , typename BinaryPredicate 
-     , typename BinaryMergeTransform 
- > 
- MultiPassIOIterator conditionalInPlaceMerge( 
-       MultiPassIOIterator cur 
-     , MultiPassIOIterator end 
-     , BinaryPredicate predicate 
-     , BinaryMergeTransform merge) 
- { 
-     MultiPassIOIterator next(cur + 1); 
-     while ((cur != end) && (next != end)) 
-     { 
-         if (predicate(*cur, *next)) 
-         { 
-             *cur = merge(*cur, *next); 
-             move(next + 1, end, next); 
-             --end; 
-         } 
-         else 
-         { 
-             ++cur; 
-             ++next; 
-         } 
-     } 
-   
-     return (cur != end) ? next : end; 
- } 
-   
- // our aggregate structure 
- struct Aggregate 
- { 
-     int key_; 
-     unsigned count_; 
- }; 
- ostream& operator<<(ostream &os, Aggregate a) 
- { 
-     os << "{ " << a.key_ << ", " << a.count_ << " }"; 
-     return os; 
- } 
- int main() { 
-     Aggregate aggregates[] = { 
-         { 12, 35 }, 
-         { 57, 503 }, 
-         { 83, 5675 }, 
-         { 12, 123 }, 
-         { 11, 578 } 
-     }; 
-     Aggregate *end(aggregates + (sizeof(aggregates) / sizeof(aggregates[0]))); 
-     // first sort 
-     sort( 
-           aggregates, end 
-         , [](Aggregate const &lhs, Aggregate const &rhs){ return lhs.key_ < rhs.key_; }); 
-     // now condense 
-     end = conditionalInPlaceMerge( 
-           aggregates 
-         , end 
-         , [](Aggregate const &lhs, Aggregate const &rhs){ return lhs.key_ == rhs.key_; } 
-         , [](Aggregate lhs, Aggregate const &rhs){ lhs.count_ += rhs.count_; return lhs; } 
-         ); 
-   
-     ostream_iterator< Aggregate > out_it(cout, "\n"); 
-     copy(aggregates, end, out_it); 
-     return 0; 
- } 
				I2luY2x1ZGUgPGFsZ29yaXRobT4KCiNpbmNsdWRlIDxpdGVyYXRvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPAogICAgICB0eXBlbmFtZSBNdWx0aVBhc3NJT0l0ZXJhdG9yCiAgICAsIHR5cGVuYW1lIEJpbmFyeVByZWRpY2F0ZQogICAgLCB0eXBlbmFtZSBCaW5hcnlNZXJnZVRyYW5zZm9ybQo+Ck11bHRpUGFzc0lPSXRlcmF0b3IgY29uZGl0aW9uYWxJblBsYWNlTWVyZ2UoCiAgICAgIE11bHRpUGFzc0lPSXRlcmF0b3IgY3VyCiAgICAsIE11bHRpUGFzc0lPSXRlcmF0b3IgZW5kCiAgICAsIEJpbmFyeVByZWRpY2F0ZSBwcmVkaWNhdGUKICAgICwgQmluYXJ5TWVyZ2VUcmFuc2Zvcm0gbWVyZ2UpCnsKICAgIE11bHRpUGFzc0lPSXRlcmF0b3IgbmV4dChjdXIgKyAxKTsKICAgIHdoaWxlICgoY3VyICE9IGVuZCkgJiYgKG5leHQgIT0gZW5kKSkKICAgIHsKICAgICAgICBpZiAocHJlZGljYXRlKCpjdXIsICpuZXh0KSkKICAgICAgICB7CiAgICAgICAgICAgICpjdXIgPSBtZXJnZSgqY3VyLCAqbmV4dCk7CiAgICAgICAgICAgIG1vdmUobmV4dCArIDEsIGVuZCwgbmV4dCk7CiAgICAgICAgICAgIC0tZW5kOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICArK2N1cjsKICAgICAgICAgICAgKytuZXh0OwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gKGN1ciAhPSBlbmQpID8gbmV4dCA6IGVuZDsKfQoKLy8gb3VyIGFnZ3JlZ2F0ZSBzdHJ1Y3R1cmUKc3RydWN0IEFnZ3JlZ2F0ZQp7CiAgICBpbnQga2V5XzsKICAgIHVuc2lnbmVkIGNvdW50XzsKfTsKb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtICZvcywgQWdncmVnYXRlIGEpCnsKICAgIG9zIDw8ICJ7ICIgPDwgYS5rZXlfIDw8ICIsICIgPDwgYS5jb3VudF8gPDwgIiB9IjsKICAgIHJldHVybiBvczsKfQppbnQgbWFpbigpIHsKICAgIEFnZ3JlZ2F0ZSBhZ2dyZWdhdGVzW10gPSB7CiAgICAgICAgeyAxMiwgMzUgfSwKICAgICAgICB7IDU3LCA1MDMgfSwKICAgICAgICB7IDgzLCA1Njc1IH0sCiAgICAgICAgeyAxMiwgMTIzIH0sCiAgICAgICAgeyAxMSwgNTc4IH0KICAgIH07CiAgICBBZ2dyZWdhdGUgKmVuZChhZ2dyZWdhdGVzICsgKHNpemVvZihhZ2dyZWdhdGVzKSAvIHNpemVvZihhZ2dyZWdhdGVzWzBdKSkpOwogICAgLy8gZmlyc3Qgc29ydAogICAgc29ydCgKICAgICAgICAgIGFnZ3JlZ2F0ZXMsIGVuZAogICAgICAgICwgW10oQWdncmVnYXRlIGNvbnN0ICZsaHMsIEFnZ3JlZ2F0ZSBjb25zdCAmcmhzKXsgcmV0dXJuIGxocy5rZXlfIDwgcmhzLmtleV87IH0pOwogICAgLy8gbm93IGNvbmRlbnNlCiAgICBlbmQgPSBjb25kaXRpb25hbEluUGxhY2VNZXJnZSgKICAgICAgICAgIGFnZ3JlZ2F0ZXMKICAgICAgICAsIGVuZAogICAgICAgICwgW10oQWdncmVnYXRlIGNvbnN0ICZsaHMsIEFnZ3JlZ2F0ZSBjb25zdCAmcmhzKXsgcmV0dXJuIGxocy5rZXlfID09IHJocy5rZXlfOyB9CiAgICAgICAgLCBbXShBZ2dyZWdhdGUgbGhzLCBBZ2dyZWdhdGUgY29uc3QgJnJocyl7IGxocy5jb3VudF8gKz0gcmhzLmNvdW50XzsgcmV0dXJuIGxoczsgfQogICAgICAgICk7CiAgICAgICAgCiAgICBvc3RyZWFtX2l0ZXJhdG9yPCBBZ2dyZWdhdGUgPiBvdXRfaXQoY291dCwgIlxuIik7CiAgICBjb3B5KGFnZ3JlZ2F0ZXMsIGVuZCwgb3V0X2l0KTsKICAgIHJldHVybiAwOwp9