#include <string>
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include "palindromy.h"
#include "message.h"
using namespace std;
class input_view 
{
    const size_t length;
public:
    class iterator
    {
        input_view const &input;
        size_t index;
    public:
        iterator(input_view const &input, size_t index) : input(input), index(index) {}
        char operator*() const { return input[index]; }
        void operator++() {++index;}
        friend bool operator==(iterator const &lhs, iterator const &rhs) { return lhs.index == rhs.index; }
        friend bool operator!=(iterator const &lhs, iterator const &rhs) { return lhs.index != rhs.index; }
        friend iterator operator+(iterator const &lhs, size_t plus) { return iterator(lhs.input, lhs.index + plus); }
        friend size_t operator-(iterator const &lhs, iterator const &rhs) { return lhs.index - rhs.index; }
    };
    input_view() : length(GetLength()) { }
    size_t size() const { return length; }
    char operator[](size_t i) const { return GetLetter(i); }
    iterator begin() const { return iterator(*this, 0); }
    iterator end() const { return iterator(*this, length); }
};
size_t get_right(pair<size_t, size_t> p) { return p.first; }
size_t get_middle(pair<size_t, size_t> p) { return p.second; }
template<typename stringlike, typename Operation>
void func(stringlike &input, Operation op)
{
    size_t length = 2*input.size()+1;
    auto haystack = [&input, length](size_t index)
    {
        return index == 0 ? '^' : index == length-1 ? '$' : index%2 == 0 ? '_' : input[index/2];
    };
    vector<size_t> max_radius(length, 0);
    pair<size_t, size_t> rightmost = {0, 0};
    for(size_t middle = 1; haystack(middle) != '$'; ++middle)
    {
        size_t &radius = max_radius[middle];
        if(get_right(rightmost) > middle)
        {
            size_t mirrored_position = 2*get_middle(rightmost) - middle;
            radius = min(get_right(rightmost) - middle, max_radius[mirrored_position]);
        }
        else
            radius = 0;
        while( haystack(middle-radius-1) == haystack(middle+radius+1) )
            ++radius;
        auto left = (middle-radius)/2;
        auto right = (middle+radius+1)/2;
        if(left != right)
            op(begin(input)+left, begin(input)+right);
        rightmost = max(rightmost, {middle+radius, middle});
    }
}
void slave(int nodes, int node) {}
void master(int nodes, int node)
{
    input_view input;
    size_t total = 0;
    func(input, [&total](input_view::iterator l, input_view::iterator r)
    {
        total += (r-l+1)/2;
    });
    cout << total << '\n';
}
int main() 
{
    int nodes, node;
    node = MyNodeId();
    nodes = NumberOfNodes();
    
    if( node == 0 )
        master(nodes, node);
    else
        slave(nodes, node);
}
        | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #include <string> #include <iostream> #include <vector> #include <array> #include <algorithm> #include "palindromy.h" #include "message.h" using namespace std; class input_view { const size_t length; public: class iterator { input_view const &input; size_t index; public: iterator(input_view const &input, size_t index) : input(input), index(index) {} char operator*() const { return input[index]; } void operator++() {++index;} friend bool operator==(iterator const &lhs, iterator const &rhs) { return lhs.index == rhs.index; } friend bool operator!=(iterator const &lhs, iterator const &rhs) { return lhs.index != rhs.index; } friend iterator operator+(iterator const &lhs, size_t plus) { return iterator(lhs.input, lhs.index + plus); } friend size_t operator-(iterator const &lhs, iterator const &rhs) { return lhs.index - rhs.index; } }; input_view() : length(GetLength()) { } size_t size() const { return length; } char operator[](size_t i) const { return GetLetter(i); } iterator begin() const { return iterator(*this, 0); } iterator end() const { return iterator(*this, length); } }; size_t get_right(pair<size_t, size_t> p) { return p.first; } size_t get_middle(pair<size_t, size_t> p) { return p.second; } template<typename stringlike, typename Operation> void func(stringlike &input, Operation op) { size_t length = 2*input.size()+1; auto haystack = [&input, length](size_t index) { return index == 0 ? '^' : index == length-1 ? '$' : index%2 == 0 ? '_' : input[index/2]; }; vector<size_t> max_radius(length, 0); pair<size_t, size_t> rightmost = {0, 0}; for(size_t middle = 1; haystack(middle) != '$'; ++middle) { size_t &radius = max_radius[middle]; if(get_right(rightmost) > middle) { size_t mirrored_position = 2*get_middle(rightmost) - middle; radius = min(get_right(rightmost) - middle, max_radius[mirrored_position]); } else radius = 0; while( haystack(middle-radius-1) == haystack(middle+radius+1) ) ++radius; auto left = (middle-radius)/2; auto right = (middle+radius+1)/2; if(left != right) op(begin(input)+left, begin(input)+right); rightmost = max(rightmost, {middle+radius, middle}); } } void slave(int nodes, int node) {} void master(int nodes, int node) { input_view input; size_t total = 0; func(input, [&total](input_view::iterator l, input_view::iterator r) { total += (r-l+1)/2; }); cout << total << '\n'; } int main() { int nodes, node; node = MyNodeId(); nodes = NumberOfNodes(); if( node == 0 ) master(nodes, node); else slave(nodes, node); } | 
 
            
         English
                    English