<commit_before>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"
#include "CellularLog.h"

using namespace mbed;

const char *QIURC_RECV = "recv";
const uint8_t QIURC_RECV_LENGTH = 4;
const char *QIURC_CLOSED = "closed";
const uint8_t QIURC_CLOSED_LENGTH = 6;
const uint8_t MAX_QIURC_LENGTH = QIURC_CLOSED_LENGTH;

QUECTEL_BG96_CellularStack::QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type)
{
    _at.set_urc_handler("+QIURC:", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc));
}

QUECTEL_BG96_CellularStack::~QUECTEL_BG96_CellularStack()
{
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
{
    CellularSocket *socket = (CellularSocket *)handle;

    int modem_connect_id = -1;
    int request_connect_id = socket->id;
    int err = -1;

    _at.lock();
    if (socket->proto == NSAPI_TCP) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("TCP");
        _at.write_string(address.get_ip_address());
        _at.write_int(address.get_port());
        _at.write_int(socket->localAddress.get_port());
        _at.write_int(0);
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            _at.cmd_start("AT+QICLOSE=");
            _at.write_int(modem_connect_id);
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("TCP");
            _at.write_string(address.get_ip_address());
            _at.write_int(address.get_port());
            _at.write_int(socket->localAddress.get_port());
            _at.write_int(0);
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    }

    // If opened successfully BUT not requested one, close it
    if (!err && (modem_connect_id != request_connect_id)) {
        _at.cmd_start("AT+QICLOSE=");
        _at.write_int(modem_connect_id);
        _at.cmd_stop();
        _at.resp_start();
        _at.resp_stop();
    }

    nsapi_error_t ret_val = _at.get_last_error();
    _at.unlock();

    if ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id)) {
        socket->created = true;
        socket->remoteAddress = address;
        socket->connected = true;
        return NSAPI_ERROR_OK;
    }

    return NSAPI_ERROR_NO_CONNECTION;
}

void QUECTEL_BG96_CellularStack::urc_qiurc()
{
    char urc_string[MAX_QIURC_LENGTH + 1];
    _at.lock();
    const int urc_string_length = _at.read_string(urc_string, sizeof(urc_string));
    const int sock_id = _at.read_int();
    const nsapi_error_t err = _at.unlock_return_error();

    if (err != NSAPI_ERROR_OK) {
        return;
    }

    bool recv = strcmp(urc_string, "recv") == 0;
    bool closed = strcmp(urc_string, "closed") == 0;

    CellularSocket *sock = find_socket(sock_id);
    if (sock) {
        if (closed) {
            tr_error("Socket closed %d", sock_id);
            sock->closed = true;
        }

        if (recv || closed) {
            if (sock->_cb) {
                sock->_cb(sock->_data);
            }
        }
    }
}

int QUECTEL_BG96_CellularStack::get_max_socket_count()
{
    return BG96_SOCKET_MAX;
}

bool QUECTEL_BG96_CellularStack::is_protocol_supported(nsapi_protocol_t protocol)
{
    return (protocol == NSAPI_UDP || protocol == NSAPI_TCP);
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_close_impl(int sock_id)
{
    _at.set_at_timeout(BG96_CLOSE_SOCKET_TIMEOUT);
    _at.cmd_start("AT+QICLOSE=");
    _at.write_int(sock_id);
    _at.cmd_stop_read_resp();
    _at.restore_at_timeout();

    return _at.get_last_error();
}

void QUECTEL_BG96_CellularStack::handle_open_socket_response(int &modem_connect_id, int &err)
{
    // OK
    _at.resp_start();
    _at.resp_stop();
    // QIOPEN -> should be handled as URC?
    _at.set_at_timeout(BG96_CREATE_SOCKET_TIMEOUT);
    _at.resp_start("+QIOPEN:");
    _at.restore_at_timeout();
    modem_connect_id = _at.read_int();
    err = _at.read_int();
}
nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *socket)
{
    int modem_connect_id = -1;
    int request_connect_id = socket->id;
    int remote_port = 0;
    int err = -1;

    if (socket->proto == NSAPI_UDP && !socket->connected) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("UDP SERVICE");
        _at.write_string("127.0.0.1");
        _at.write_int(remote_port);
        _at.write_int(socket->localAddress.get_port());
        _at.write_int(0);
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            _at.cmd_start("AT+QICLOSE=");
            _at.write_int(modem_connect_id);
            _at.cmd_stop_read_resp();

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("UDP SERVICE");
            _at.write_string("127.0.0.1");
            _at.write_int(remote_port);
            _at.write_int(socket->localAddress.get_port());
            _at.write_int(0);
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    } else if (socket->proto == NSAPI_UDP && socket->connected) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("UDP");
        _at.write_string(socket->remoteAddress.get_ip_address());
        _at.write_int(socket->remoteAddress.get_port());
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            _at.cmd_start("AT+QICLOSE=");
            _at.write_int(modem_connect_id);
            _at.cmd_stop_read_resp();

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("UDP");
            _at.write_string(socket->remoteAddress.get_ip_address());
            _at.write_int(socket->remoteAddress.get_port());
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    }

    // If opened successfully BUT not requested one, close it
    if (!err && (modem_connect_id != request_connect_id)) {
        _at.cmd_start("AT+QICLOSE=");
        _at.write_int(modem_connect_id);
        _at.cmd_stop_read_resp();
    }

    nsapi_error_t ret_val = _at.get_last_error();

    socket->created = ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id));

    return ret_val;
}

nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
                                                                     const void *data, nsapi_size_t size)
{
    if (size > BG96_MAX_SEND_SIZE) {
        return NSAPI_ERROR_PARAMETER;
    }

    int sent_len = 0;
    int sent_len_before = 0;
    int sent_len_after = 0;

    // Get the sent count before sending
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(0);
    _at.cmd_stop();

    _at.resp_start("+QISEND:");
    sent_len_before = _at.read_int();
    _at.resp_stop();

    // Send
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(size);
    if (socket->proto == NSAPI_UDP) {
        _at.write_string(address.get_ip_address());
        _at.write_int(address.get_port());
    }
    _at.cmd_stop();

    _at.resp_start(">");
    _at.write_bytes((uint8_t *)data, size);
    _at.resp_start();
    _at.set_stop_tag("\r\n");
    _at.resp_stop();

    // Get the sent count after sending
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(0);
    _at.cmd_stop();

    _at.resp_start("+QISEND:");
    sent_len_after = _at.read_int();
    _at.resp_stop();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        sent_len = sent_len_after - sent_len_before;
        return sent_len;
    }

    return _at.get_last_error();
}

nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
                                                                       void *buffer, nsapi_size_t size)
{
    nsapi_size_or_error_t recv_len = 0;
    int port;
    char ip_address[NSAPI_IP_SIZE + 1];

    _at.cmd_start("AT+QIRD=");
    _at.write_int(socket->id);
    if (socket->proto == NSAPI_TCP) {
        // do not read more than max size
        size = size > BG96_MAX_RECV_SIZE ? BG96_MAX_RECV_SIZE : size;
        _at.write_int(size);
    }
    _at.cmd_stop();

    _at.resp_start("+QIRD:");
    recv_len = _at.read_int();
    _at.read_string(ip_address, sizeof(ip_address));
    port = _at.read_int();
    if (recv_len > 0) {
        // do not read more than buffer size
        recv_len = recv_len > (nsapi_size_or_error_t)size ? size : recv_len;
        _at.read_bytes((uint8_t *)buffer, recv_len);
    }
    _at.resp_stop();

    // We block only if 0 recv length really means no data.
    // If 0 is followed by ip address and port can be an UDP 0 length packet
    if (!recv_len && port < 0) {
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    if (address) {
        address->set_ip_address(ip_address);
        address->set_port(port);
    }

    return recv_len;
}
<commit_msg>Add a check step of IPv6 network to BG96<commit_after>/*
 * Copyright (c) 2017, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"
#include "CellularLog.h"

using namespace mbed;

const char *QIURC_RECV = "recv";
const uint8_t QIURC_RECV_LENGTH = 4;
const char *QIURC_CLOSED = "closed";
const uint8_t QIURC_CLOSED_LENGTH = 6;
const uint8_t MAX_QIURC_LENGTH = QIURC_CLOSED_LENGTH;

QUECTEL_BG96_CellularStack::QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type)
{
    _at.set_urc_handler("+QIURC:", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc));
}

QUECTEL_BG96_CellularStack::~QUECTEL_BG96_CellularStack()
{
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
{
    return NSAPI_ERROR_UNSUPPORTED;
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
{
    CellularSocket *socket = (CellularSocket *)handle;

    int modem_connect_id = -1;
    int request_connect_id = socket->id;
    int err = -1;

    _at.lock();
    if (socket->proto == NSAPI_TCP) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("TCP");
        _at.write_string(address.get_ip_address());
        _at.write_int(address.get_port());
        _at.write_int(socket->localAddress.get_port());
        _at.write_int(0);
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            _at.cmd_start("AT+QICLOSE=");
            _at.write_int(modem_connect_id);
            _at.cmd_stop();
            _at.resp_start();
            _at.resp_stop();

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("TCP");
            _at.write_string(address.get_ip_address());
            _at.write_int(address.get_port());
            _at.write_int(socket->localAddress.get_port());
            _at.write_int(0);
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    }

    // If opened successfully BUT not requested one, close it
    if (!err && (modem_connect_id != request_connect_id)) {
        _at.cmd_start("AT+QICLOSE=");
        _at.write_int(modem_connect_id);
        _at.cmd_stop();
        _at.resp_start();
        _at.resp_stop();
    }

    nsapi_error_t ret_val = _at.get_last_error();
    _at.unlock();

    if ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id)) {
        socket->created = true;
        socket->remoteAddress = address;
        socket->connected = true;
        return NSAPI_ERROR_OK;
    }

    return NSAPI_ERROR_NO_CONNECTION;
}

void QUECTEL_BG96_CellularStack::urc_qiurc()
{
    char urc_string[MAX_QIURC_LENGTH + 1];
    _at.lock();
    const int urc_string_length = _at.read_string(urc_string, sizeof(urc_string));
    const int sock_id = _at.read_int();
    const nsapi_error_t err = _at.unlock_return_error();

    if (err != NSAPI_ERROR_OK) {
        return;
    }

    bool recv = strcmp(urc_string, "recv") == 0;
    bool closed = strcmp(urc_string, "closed") == 0;

    CellularSocket *sock = find_socket(sock_id);
    if (sock) {
        if (closed) {
            tr_error("Socket closed %d", sock_id);
            sock->closed = true;
        }

        if (recv || closed) {
            if (sock->_cb) {
                sock->_cb(sock->_data);
            }
        }
    }
}

int QUECTEL_BG96_CellularStack::get_max_socket_count()
{
    return BG96_SOCKET_MAX;
}

bool QUECTEL_BG96_CellularStack::is_protocol_supported(nsapi_protocol_t protocol)
{
    return (protocol == NSAPI_UDP || protocol == NSAPI_TCP);
}

nsapi_error_t QUECTEL_BG96_CellularStack::socket_close_impl(int sock_id)
{
    _at.set_at_timeout(BG96_CLOSE_SOCKET_TIMEOUT);
    _at.cmd_start("AT+QICLOSE=");
    _at.write_int(sock_id);
    _at.cmd_stop_read_resp();
    _at.restore_at_timeout();

    return _at.get_last_error();
}

void QUECTEL_BG96_CellularStack::handle_open_socket_response(int &modem_connect_id, int &err)
{
    // OK
    _at.resp_start();
    _at.resp_stop();
    // QIOPEN -> should be handled as URC?
    _at.set_at_timeout(BG96_CREATE_SOCKET_TIMEOUT);
    _at.resp_start("+QIOPEN:");
    _at.restore_at_timeout();
    modem_connect_id = _at.read_int();
    err = _at.read_int();
}
nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *socket)
{
    int modem_connect_id = -1;
    int request_connect_id = socket->id;
    int remote_port = 0;
    int err = -1;

    if (socket->proto == NSAPI_UDP && !socket->connected) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("UDP SERVICE");
        if (_stack_type == IPV4_STACK) {
            _at.write_string("127.0.0.1");
        } else if (_stack_type == IPV6_STACK || _stack_type == IPV4V6_STACK) {
            _at.write_string("0:0:0:0:0:0:0:1");
        }
        _at.write_int(remote_port);
        _at.write_int(socket->localAddress.get_port());
        _at.write_int(0);
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            socket_close_impl(modem_connect_id);

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("UDP SERVICE");

            if (_stack_type == IPV4_STACK) {
                _at.write_string("127.0.0.1");
            } else if (_stack_type == IPV6_STACK || _stack_type == IPV4V6_STACK) {
                _at.write_string("0:0:0:0:0:0:0:1");
            }
            _at.write_int(remote_port);
            _at.write_int(socket->localAddress.get_port());
            _at.write_int(0);
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    } else if (socket->proto == NSAPI_UDP && socket->connected) {
        _at.cmd_start("AT+QIOPEN=");
        _at.write_int(_cid);
        _at.write_int(request_connect_id);
        _at.write_string("UDP");
        _at.write_string(socket->remoteAddress.get_ip_address());
        _at.write_int(socket->remoteAddress.get_port());
        _at.cmd_stop();

        handle_open_socket_response(modem_connect_id, err);

        if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) {
            if (err == BG96_SOCKET_BIND_FAIL) {
                socket->created = false;
                return NSAPI_ERROR_PARAMETER;
            }
            socket_close_impl(modem_connect_id);

            _at.cmd_start("AT+QIOPEN=");
            _at.write_int(_cid);
            _at.write_int(request_connect_id);
            _at.write_string("UDP");
            _at.write_string(socket->remoteAddress.get_ip_address());
            _at.write_int(socket->remoteAddress.get_port());
            _at.cmd_stop();

            handle_open_socket_response(modem_connect_id, err);
        }
    }

    // If opened successfully BUT not requested one, close it
    if (!err && (modem_connect_id != request_connect_id)) {
        socket_close_impl(modem_connect_id);
    }

    nsapi_error_t ret_val = _at.get_last_error();

    socket->created = ((ret_val == NSAPI_ERROR_OK) && (modem_connect_id == request_connect_id));

    return ret_val;
}

nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
                                                                     const void *data, nsapi_size_t size)
{
    if (size > BG96_MAX_SEND_SIZE) {
        return NSAPI_ERROR_PARAMETER;
    }

    int sent_len = 0;
    int sent_len_before = 0;
    int sent_len_after = 0;

    // Get the sent count before sending
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(0);
    _at.cmd_stop();

    _at.resp_start("+QISEND:");
    sent_len_before = _at.read_int();
    _at.resp_stop();

    // Send
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(size);
    if (socket->proto == NSAPI_UDP) {
        _at.write_string(address.get_ip_address());
        _at.write_int(address.get_port());
    }
    _at.cmd_stop();

    _at.resp_start(">");
    _at.write_bytes((uint8_t *)data, size);
    _at.resp_start();
    _at.set_stop_tag("\r\n");
    _at.resp_stop();

    // Get the sent count after sending
    _at.cmd_start("AT+QISEND=");
    _at.write_int(socket->id);
    _at.write_int(0);
    _at.cmd_stop();

    _at.resp_start("+QISEND:");
    sent_len_after = _at.read_int();
    _at.resp_stop();

    if (_at.get_last_error() == NSAPI_ERROR_OK) {
        sent_len = sent_len_after - sent_len_before;
        return sent_len;
    }

    return _at.get_last_error();
}

nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
                                                                       void *buffer, nsapi_size_t size)
{
    nsapi_size_or_error_t recv_len = 0;
    int port;
    char ip_address[NSAPI_IP_SIZE + 1];

    _at.cmd_start("AT+QIRD=");
    _at.write_int(socket->id);
    if (socket->proto == NSAPI_TCP) {
        // do not read more than max size
        size = size > BG96_MAX_RECV_SIZE ? BG96_MAX_RECV_SIZE : size;
        _at.write_int(size);
    }
    _at.cmd_stop();

    _at.resp_start("+QIRD:");
    recv_len = _at.read_int();
    _at.read_string(ip_address, sizeof(ip_address));
    port = _at.read_int();
    if (recv_len > 0) {
        // do not read more than buffer size
        recv_len = recv_len > (nsapi_size_or_error_t)size ? size : recv_len;
        _at.read_bytes((uint8_t *)buffer, recv_len);
    }
    _at.resp_stop();

    // We block only if 0 recv length really means no data.
    // If 0 is followed by ip address and port can be an UDP 0 length packet
    if (!recv_len && port < 0) {
        return NSAPI_ERROR_WOULD_BLOCK;
    }

    if (address) {
        address->set_ip_address(ip_address);
        address->set_port(port);
    }

    return recv_len;
}
<|endoftext|>


<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "filedistributionmodel.h"
#include "zkfiledbmodel.h"
#include "deployedfilestodownload.h"
#include "filedistributionmodelimpl.h"
#include <vespa/vespalib/util/stringfmt.h>
#include <boost/filesystem.hpp>
#include <zookeeper/zookeeper.h>

#include <vespa/log/log.h>
LOG_SETUP(".filedistributionmodel");

namespace fs = boost::filesystem;

using filedistribution::ZKFileDBModel;

namespace {
//peer format:  hostName:port

void
addPeerEntry(const std::string& peer,
    filedistribution::FileDistributionModelImpl::PeerEntries& result) {

    try {
        libtorrent::peer_entry peerEntry;
        peerEntry.pid.clear();

        std::istringstream stream(peer);
        stream.exceptions ( std::istream::failbit | std::istream::badbit );

        std::getline(stream, peerEntry.ip, ZKFileDBModel::_peerEntrySeparator);
        stream >> peerEntry.port;

        result.push_back(peerEntry);
    } catch (const std::exception&) {
        LOG(warning, "Invalid peer entry: '%s'", peer.c_str());
        //Ignore invalid peer entries
    }
}

std::vector<std::string>::iterator
prunePeers(std::vector<std::string> &peers, size_t maxPeers) {
    if (peers.size() <= maxPeers)
        return peers.end();

    assert (maxPeers < 2147483648); //due to the usage of rand()

    const size_t peersSize = peers.size();
    for (size_t i=0; i<maxPeers; ++i) {
        //i <= i + (std::rand() % ( peersSize -i )) <= peerSize - 1
        size_t candidateBetween_i_and_peerSize = i + ( std::rand() % ( peersSize -i ));
        std::swap(peers[i], peers[candidateBetween_i_and_peerSize]);
    }

    return peers.begin() + maxPeers;
}

} //anonymous namespace

namespace filedistribution {

VESPA_IMPLEMENT_EXCEPTION(NotPeer, vespalib::Exception);

}

using filedistribution::FileDistributionModelImpl;

struct FileDistributionModelImpl::DeployedFilesChangedCallback :
    public ZKFacade::NodeChangedWatcher
{
    typedef std::shared_ptr<DeployedFilesChangedCallback> SP;

    std::weak_ptr<FileDistributionModelImpl> _parent;

    DeployedFilesChangedCallback(
            const std::shared_ptr<FileDistributionModelImpl> & parent)
        :_parent(parent)
    {}

    //override
    void operator()() override {
        if (std::shared_ptr<FileDistributionModelImpl> model = _parent.lock()) {
            model->_filesToDownloadChanged();
        }
    }
};

FileDistributionModelImpl::~FileDistributionModelImpl() {
    LOG(debug, "Deconstructing FileDistributionModelImpl");
}

FileDistributionModelImpl::PeerEntries
FileDistributionModelImpl::getPeers(const std::string& fileReference, size_t maxPeers) {
    try {
        fs::path path = _fileDBModel.getPeersPath(fileReference);

        typedef std::vector<std::string> Peers;
        Peers peers = _zk->getChildren(path);
        // TODO: Take this port from some config somewhere instead of hardcoding
        addConfigServersAsPeers(peers, getenv("services__addr_configserver"), 19093);

        Peers::iterator end = prunePeers(peers, maxPeers);

        PeerEntries result;
        result.reserve(end - peers.begin());

        std::for_each(peers.begin(), end, [&] (const std::string & s) { addPeerEntry(s, result); });

        LOG(debug, "Found %zu peers for path '%s'", result.size(), path.string().c_str());
        return result;
    } catch(ZKNodeDoesNotExistsException&) {
        LOG(debug, ("No peer entries available for " + fileReference).c_str());
        return PeerEntries();
    }
}

fs::path
FileDistributionModelImpl::getPeerEntryPath(const std::string& fileReference) {
    std::ostringstream entry;
    entry <<_hostName
          <<ZKFileDBModel::_peerEntrySeparator <<_port;

    return _fileDBModel.getPeersPath(fileReference) / entry.str();
}

void
FileDistributionModelImpl::addPeer(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Adding peer '%s'", path.string().c_str());

    if (_zk->hasNode(path)) {
        LOG(info, "Retiring previous peer node owner.");
        _zk->removeIfExists(path);
    }
    _zk->addEphemeralNode(path);
}

void
FileDistributionModelImpl::removePeer(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Removing peer '%s'", path.string().c_str());

    _zk->removeIfExists(path);
}

//Assumes that addPeer has been called before the torrent was started,
//so that we avoid the race condition between finishing downloading a torrent
//and setting peer status
void
FileDistributionModelImpl::peerFinished(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Peer finished '%s'", path.string().c_str());

    try {
        bool mustExist = true;
        char progress = 100; //percent

        _zk->setData(path, &progress, sizeof(char), mustExist);
    } catch(ZKNodeDoesNotExistsException & e) {
        NotPeer(fileReference, e, VESPA_STRLOC);
    }
}

std::set<std::string>
FileDistributionModelImpl::getFilesToDownload() {
    DeployedFilesToDownload d(_zk.get());
    std::vector<std::string> deployed = d.getDeployedFilesToDownload(_hostName,
            DeployedFilesChangedCallback::SP(
                    new DeployedFilesChangedCallback(shared_from_this())));

    std::set<std::string> result(deployed.begin(), deployed.end());

    {
        LockGuard guard(_activeFileReferencesMutex);
        result.insert(_activeFileReferences.begin(), _activeFileReferences.end());
    }
    return result;
}

bool
FileDistributionModelImpl::updateActiveFileReferences(
    const std::vector<vespalib::string>& fileReferences) {

    std::vector<vespalib::string> sortedFileReferences(fileReferences);
    std::sort(sortedFileReferences.begin(), sortedFileReferences.end());

    LockGuard guard(_activeFileReferencesMutex);
    bool changed =
        sortedFileReferences != _activeFileReferences;

    sortedFileReferences.swap(_activeFileReferences);
    return changed;
}

void
FileDistributionModelImpl::addConfigServersAsPeers(
    std::vector<std::string> & peers, char const* envConfigServers, int port) {

    std::set<std::string> peersFromTracker(peers.begin(), peers.end());

    if (envConfigServers == NULL) {
        // Could be standalone cluster (not set for this).
        return;
    }
    std::string configServerCommaListed(envConfigServers);
    std::stringstream configserverstream(configServerCommaListed);
    std::string configserver;
    while (std::getline(configserverstream, configserver, ',')) {
         configserver += ":" + std::to_string(port);
         if (peersFromTracker.find(configserver) ==  peersFromTracker.end()) {
             peers.push_back(configserver);
             LOG(debug, "Adding configserver '%s'", configserver.c_str());
         } else {
             LOG(debug, "Configserver already added '%s'", configserver.c_str());
	 }
    }
}

void
FileDistributionModelImpl::configure(std::unique_ptr<FilereferencesConfig> config) {
    const bool changed = updateActiveFileReferences(config->filereferences);
    if (changed) {
        try {
            _filesToDownloadChanged();
        } catch (const ZKConnectionLossException & e) {
            LOG(info, "Connection loss in reconfigure of file references, resuming. %s", e.what());
        }
    }
}
<commit_msg>On timeout we will just do a quick restart and start over.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "filedistributionmodel.h"
#include "zkfiledbmodel.h"
#include "deployedfilestodownload.h"
#include "filedistributionmodelimpl.h"
#include <vespa/vespalib/util/stringfmt.h>
#include <boost/filesystem.hpp>
#include <zookeeper/zookeeper.h>

#include <vespa/log/log.h>
LOG_SETUP(".filedistributionmodel");

namespace fs = boost::filesystem;

using filedistribution::ZKFileDBModel;

namespace {
//peer format:  hostName:port

void
addPeerEntry(const std::string& peer,
    filedistribution::FileDistributionModelImpl::PeerEntries& result) {

    try {
        libtorrent::peer_entry peerEntry;
        peerEntry.pid.clear();

        std::istringstream stream(peer);
        stream.exceptions ( std::istream::failbit | std::istream::badbit );

        std::getline(stream, peerEntry.ip, ZKFileDBModel::_peerEntrySeparator);
        stream >> peerEntry.port;

        result.push_back(peerEntry);
    } catch (const std::exception&) {
        LOG(warning, "Invalid peer entry: '%s'", peer.c_str());
        //Ignore invalid peer entries
    }
}

std::vector<std::string>::iterator
prunePeers(std::vector<std::string> &peers, size_t maxPeers) {
    if (peers.size() <= maxPeers)
        return peers.end();

    assert (maxPeers < 2147483648); //due to the usage of rand()

    const size_t peersSize = peers.size();
    for (size_t i=0; i<maxPeers; ++i) {
        //i <= i + (std::rand() % ( peersSize -i )) <= peerSize - 1
        size_t candidateBetween_i_and_peerSize = i + ( std::rand() % ( peersSize -i ));
        std::swap(peers[i], peers[candidateBetween_i_and_peerSize]);
    }

    return peers.begin() + maxPeers;
}

} //anonymous namespace

namespace filedistribution {

VESPA_IMPLEMENT_EXCEPTION(NotPeer, vespalib::Exception);

}

using filedistribution::FileDistributionModelImpl;

struct FileDistributionModelImpl::DeployedFilesChangedCallback :
    public ZKFacade::NodeChangedWatcher
{
    typedef std::shared_ptr<DeployedFilesChangedCallback> SP;

    std::weak_ptr<FileDistributionModelImpl> _parent;

    DeployedFilesChangedCallback(
            const std::shared_ptr<FileDistributionModelImpl> & parent)
        :_parent(parent)
    {}

    //override
    void operator()() override {
        if (std::shared_ptr<FileDistributionModelImpl> model = _parent.lock()) {
            model->_filesToDownloadChanged();
        }
    }
};

FileDistributionModelImpl::~FileDistributionModelImpl() {
    LOG(debug, "Deconstructing FileDistributionModelImpl");
}

FileDistributionModelImpl::PeerEntries
FileDistributionModelImpl::getPeers(const std::string& fileReference, size_t maxPeers) {
    try {
        fs::path path = _fileDBModel.getPeersPath(fileReference);

        typedef std::vector<std::string> Peers;
        Peers peers = _zk->getChildren(path);
        // TODO: Take this port from some config somewhere instead of hardcoding
        addConfigServersAsPeers(peers, getenv("services__addr_configserver"), 19093);

        Peers::iterator end = prunePeers(peers, maxPeers);

        PeerEntries result;
        result.reserve(end - peers.begin());

        std::for_each(peers.begin(), end, [&] (const std::string & s) { addPeerEntry(s, result); });

        LOG(debug, "Found %zu peers for path '%s'", result.size(), path.string().c_str());
        return result;
    } catch(ZKNodeDoesNotExistsException&) {
        LOG(debug, ("No peer entries available for " + fileReference).c_str());
        return PeerEntries();
    }
}

fs::path
FileDistributionModelImpl::getPeerEntryPath(const std::string& fileReference) {
    std::ostringstream entry;
    entry <<_hostName
          <<ZKFileDBModel::_peerEntrySeparator <<_port;

    return _fileDBModel.getPeersPath(fileReference) / entry.str();
}

void
FileDistributionModelImpl::addPeer(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Adding peer '%s'", path.string().c_str());

    if (_zk->hasNode(path)) {
        LOG(info, "Retiring previous peer node owner.");
        _zk->removeIfExists(path);
    }
    _zk->addEphemeralNode(path);
}

void
FileDistributionModelImpl::removePeer(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Removing peer '%s'", path.string().c_str());

    _zk->removeIfExists(path);
}

//Assumes that addPeer has been called before the torrent was started,
//so that we avoid the race condition between finishing downloading a torrent
//and setting peer status
void
FileDistributionModelImpl::peerFinished(const std::string& fileReference) {
    fs::path path = getPeerEntryPath(fileReference);
    LOG(debug, "Peer finished '%s'", path.string().c_str());

    try {
        bool mustExist = true;
        char progress = 100; //percent

        _zk->setData(path, &progress, sizeof(char), mustExist);
    } catch(ZKNodeDoesNotExistsException & e) {
        NotPeer(fileReference, e, VESPA_STRLOC);
    }
}

std::set<std::string>
FileDistributionModelImpl::getFilesToDownload() {
    DeployedFilesToDownload d(_zk.get());
    std::vector<std::string> deployed = d.getDeployedFilesToDownload(_hostName,
            DeployedFilesChangedCallback::SP(
                    new DeployedFilesChangedCallback(shared_from_this())));

    std::set<std::string> result(deployed.begin(), deployed.end());

    {
        LockGuard guard(_activeFileReferencesMutex);
        result.insert(_activeFileReferences.begin(), _activeFileReferences.end());
    }
    return result;
}

bool
FileDistributionModelImpl::updateActiveFileReferences(
    const std::vector<vespalib::string>& fileReferences) {

    std::vector<vespalib::string> sortedFileReferences(fileReferences);
    std::sort(sortedFileReferences.begin(), sortedFileReferences.end());

    LockGuard guard(_activeFileReferencesMutex);
    bool changed =
        sortedFileReferences != _activeFileReferences;

    sortedFileReferences.swap(_activeFileReferences);
    return changed;
}

void
FileDistributionModelImpl::addConfigServersAsPeers(
    std::vector<std::string> & peers, char const* envConfigServers, int port) {

    std::set<std::string> peersFromTracker(peers.begin(), peers.end());

    if (envConfigServers == NULL) {
        // Could be standalone cluster (not set for this).
        return;
    }
    std::string configServerCommaListed(envConfigServers);
    std::stringstream configserverstream(configServerCommaListed);
    std::string configserver;
    while (std::getline(configserverstream, configserver, ',')) {
         configserver += ":" + std::to_string(port);
         if (peersFromTracker.find(configserver) ==  peersFromTracker.end()) {
             peers.push_back(configserver);
             LOG(debug, "Adding configserver '%s'", configserver.c_str());
         } else {
             LOG(debug, "Configserver already added '%s'", configserver.c_str());
	 }
    }
}

void
FileDistributionModelImpl::configure(std::unique_ptr<FilereferencesConfig> config) {
    const bool changed = updateActiveFileReferences(config->filereferences);
    if (changed) {
        try {
            _filesToDownloadChanged();
        } catch (const ZKConnectionLossException & e) {
            LOG(info, "Connection loss in reconfigure of file references, resuming. %s", e.what());
        } catch (const ZKOperationTimeoutException & e) {
            LOG(warning, "Operation timed out in reconfigure of file references. "
                         "Will do quick exit to start a clean sheet. %s", e.what());
            std::quick_exit(41);
        }
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int main () {
  ll K;
  cin >> K;
  cout << 2 << endl;
  cout << (K+2)/2 << " " << (K+2) - (K+2)/2 << endl;
}
<commit_msg>tried D.cpp to 'D'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int main () {
  ll K;
  cin >> K;
  if (K%2 != 0) {
    cout << 2 << endl;
    cout << (K+2)/2 << " " << (K+2) - (K+2)/2 << endl;
  }
  return 1;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

bool visited[110];
vector<edge> V[110];

void add_edge(int from, int to, ll cap) {
  V[from].push_back(edge{to, cap, (int)V[to].size()});
  V[to].push_back(edge{from, 0, (int)V[from].size()-1});
}

ll dfs(int src, int dst, ll f) {
  if (src == dst) return f;
  visited[src] = true;
  for (auto &x : V[src]) {
    if (!visited[x.to] && x.cap > 0) {
      ll d = dfs(x.to, dst, min(f, x.cap));
      if (d > 0) {
        x.cap -= d;
        V[x.to][x.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int src, int dst) {
  ll flow = 0;
  while (true) {
    fill(visited, visited+110, false);
    ll f = dfs(src, dst, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

int H, W;
string a[110];

int num(int i, int j) {
  return i * H + j;
}

int main () {
  cin >> H >> W;
  for (auto i = 0; i < H; ++i) {
    cin >> a[i];
  }
  int S, T;
  int si, sj, ti, tj;
  for (auto i = 0; i < H; ++i) {
    for (auto j = 0; j < W; ++j) {
      if (a[i][j] == 'S') {
        si = i;
        sj = j;
        S = num(i, j);
        a[i][j] = 'o';
      } else if (a[i][j] == 'T') {
        ti = i;
        tj = j;
        T = num(i, j);
        a[i][j] = 'o';
      }
    }
  }
  if (si == ti || sj == tj) {
    cout << -1 << endl;
    return 0;
  }
  for (auto i = 0; i < H; ++i) {
    vector<int> X;
    for (auto j = 0; j < W; ++j) {
      if (a[i][j] == 'o') {
        X.push_back(num(i, j));
      }
    }
    for (auto it = X.begin(); it+1 != X.end(); ++it) {
      add_edge(*it, *(it+1), 1);
      add_edge(*(it+1), *it, 1);
    }
  }
  for (auto j = 0; j < W; ++j) {
    vector<int> X;
    for (auto i = 0; i < H; ++i) {
      if (a[i][j] == 'o') {
        X.push_back(num(i, j));
      }
    }
    for (auto it = X.begin(); it+1 != X.end(); ++it) {
      add_edge(*it, *(it+1), 1);
      add_edge(*(it+1), *it, 1);
    }
  }
  cout << max_flow(S, T) << endl;
}
<commit_msg>tried F.cpp to 'F'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

bool visited[10010];
vector<edge> V[10010];

void add_edge(int from, int to, ll cap) {
  V[from].push_back(edge{to, cap, (int)V[to].size()});
  V[to].push_back(edge{from, 0, (int)V[from].size()-1});
}

ll dfs(int src, int dst, ll f) {
  if (src == dst) return f;
  visited[src] = true;
  for (auto &x : V[src]) {
    if (!visited[x.to] && x.cap > 0) {
      ll d = dfs(x.to, dst, min(f, x.cap));
      if (d > 0) {
        x.cap -= d;
        V[x.to][x.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int src, int dst) {
  ll flow = 0;
  while (true) {
    fill(visited, visited+10010, false);
    ll f = dfs(src, dst, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

int H, W;
string a[110];

int num(int i, int j) {
  return i * H + j;
}

int main () {
  cin >> H >> W;
  for (auto i = 0; i < H; ++i) {
    cin >> a[i];
  }
  int S, T;
  int si, sj, ti, tj;
  for (auto i = 0; i < H; ++i) {
    for (auto j = 0; j < W; ++j) {
      if (a[i][j] == 'S') {
        si = i;
        sj = j;
        S = num(i, j);
        a[i][j] = 'o';
      } else if (a[i][j] == 'T') {
        ti = i;
        tj = j;
        T = num(i, j);
        a[i][j] = 'o';
      }
    }
  }
  if (si == ti || sj == tj) {
    cout << -1 << endl;
    return 0;
  }
  for (auto i = 0; i < H; ++i) {
    vector<int> X;
    for (auto j = 0; j < W; ++j) {
      if (a[i][j] == 'o') {
        X.push_back(num(i, j));
      }
    }
    for (auto it = X.begin(); it+1 != X.end(); ++it) {
      add_edge(*it, *(it+1), 1);
      add_edge(*(it+1), *it, 1);
    }
  }
  for (auto j = 0; j < W; ++j) {
    vector<int> X;
    for (auto i = 0; i < H; ++i) {
      if (a[i][j] == 'o') {
        X.push_back(num(i, j));
      }
    }
    for (auto it = X.begin(); it+1 != X.end(); ++it) {
      add_edge(*it, *(it+1), 1);
      add_edge(*(it+1), *it, 1);
    }
  }
  cout << max_flow(S, T) << endl;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int string_to_sum(string S)
{
  int sum = 0;
  for (auto var : S)
  {
    sum += var - '0';
  }
  return sum;
}

int main()
{
  int N, A, B;
  cin >> N >> A >> B;
  int ans = 0;
  for (auto i = 1; i <= N; i++)
  {
    cerr << "i = " << i << endl;
    int s = string_to_sum(to_string(i));
    if (A <= s && s <= B)
    {
      ans += i;
    }
  }
  cout << ans << endl;
}<commit_msg>submit B.cpp to 'B - Some Sums' (abc083) [C++14 (Clang 3.8.0)]<commit_after>#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int string_to_sum(string S)
{
  int sum = 0;
  for (auto var : S)
  {
    sum += var - '0';
  }
  return sum;
}

int main()
{
  int N, A, B;
  cin >> N >> A >> B;
  int ans = 0;
  for (auto i = 1; i <= N; i++)
  {
    int s = string_to_sum(to_string(i));
    if (A <= s && s <= B)
    {
      ans += i;
    }
  }
  cout << ans << endl;
}<|endoftext|>


<commit_before>/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-3-12 16:05:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 1 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int grundy(int a, int k)
{
  #if DEBUG == 1
  cerr << "a = " << a << ", k = " << k << endl;
  #endif
  if (a % k == 0)
    return a / k;
  int d = a / k;
  int x = (a - k * d) / (d + 1) + 1;
  return grundy(a - x * (d + 1), k);
}

int main()
{
  int N;
  int A[210];
  int K[210];
  int g[210];
  cin >> N;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i] >> K[i];
    g[i] = grundy(A[i], K[i]);
  }
  int x = 0;
  for (auto i = 0; i < N; i++)
  {
    x = x ^ g[i];
  }
  if (x != 0)
  {
    cout << "Takahashi" << endl;
  }
  else
  {
    cout << "Aoki" << endl;
  }
}<commit_msg>submit F.cpp to 'F - Strange Nim' (arc091) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-3-12 16:05:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int grundy(int a, int k)
{
  #if DEBUG == 1
  cerr << "a = " << a << ", k = " << k << endl;
  #endif
  if (a % k == 0)
    return a / k;
  int d = a / k;
  int x = (a - k * d) / (d + 1) + 1;
  x = min(a / (d + 1), x);
  return grundy(a - x * (d + 1), k);
}

int main()
{
  int N;
  int A[210];
  int K[210];
  int g[210];
  cin >> N;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i] >> K[i];
    g[i] = grundy(A[i], K[i]);
  }
  int x = 0;
  for (auto i = 0; i < N; i++)
  {
    x = x ^ g[i];
  }
  if (x != 0)
  {
    cout << "Takahashi" << endl;
  }
  else
  {
    cout << "Aoki" << endl;
  }
}<|endoftext|>


<commit_before>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 12/29/2018, 10:01:22 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = ((MOD - inv[MOD % i]) * (MOD / i)) % MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = (i * fact[i - 1]) % MOD;
    factinv[i] = (inv[i] * factinv[i - 1]) % MOD;
  }
}

long long C(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
  }
  return 0;
}

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

long long gcd(long long x, long long y)
{
  return y ? gcd(y, x % y) : x;
}

ll N;
ll Q;
ll A[3010];
int X[3010];
int Y[3010];
ll T[3010][3010];
ll t_half[3010];
ll t_half_rev[3010];

void flush()
{
  ll ans = 0;
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      ans += T[i][j];
      ans %= MOD;
    }
  }
  cout << ans << endl;
}

int main()
{
  init();
  cin >> N >> Q;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < Q; i++)
  {
    cin >> X[i] >> Y[i];
    X[i]--;
    Y[i]--;
  }
  fill(&T[0][0], &T[0][0] + 3010 * 3010, 0);
  ll initial = power(2, Q);
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < N; j++)
    {
      if (A[i] > A[j])
      {
        T[i][j] = initial;
      }
    }
  }
  ll two_inv = inv[2];
  for (auto i = 0; i < Q; i++)
  {
    int x = X[i];
    int y = Y[i];
    for (auto j = 0; j < N; j++)
    {
      if (j != x && j != y)
      {
        t_half[j] = (T[j][x] + T[j][y]) * two_inv;
        t_half[j] %= MOD;
        t_half_rev[j] = (T[x][j] + T[y][j]) * two_inv;
        t_half_rev[j] %= MOD;
      }
    }
    for (auto j = 0; j < N; j++)
    {
      if (j != x && j != y)
      {
        T[j][x] = t_half[j];
        T[j][y] = t_half[j];
        T[x][j] = t_half_rev[j];
        T[y][j] = t_half_rev[j];
      }
    }
    swap(T[x][y], T[y][x]);
    /*
    cerr << "i = " << i << endl;
    for (auto j = 0; j < N; j++)
    {
      for (auto k = 0; k < N; k++)
      {
        cerr << "T[" << j << "][" << k << "] = " << T[j][k] << endl;
      }
    }
    */
  }
  flush();
}<commit_msg>tried D.cpp to 'D'<commit_after>/**
 * File    : D.cpp
 * Author  : Kazune Takahashi
 * Created : 12/29/2018, 10:01:22 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;

const int MAX_SIZE = 1000010;
const long long MOD = 1000000007;

long long inv[MAX_SIZE];
long long fact[MAX_SIZE];
long long factinv[MAX_SIZE];

void init()
{
  inv[1] = 1;
  for (int i = 2; i < MAX_SIZE; i++)
  {
    inv[i] = ((MOD - inv[MOD % i]) * (MOD / i)) % MOD;
  }
  fact[0] = factinv[0] = 1;
  for (int i = 1; i < MAX_SIZE; i++)
  {
    fact[i] = (i * fact[i - 1]) % MOD;
    factinv[i] = (inv[i] * factinv[i - 1]) % MOD;
  }
}

long long C(int n, int k)
{
  if (n >= 0 && k >= 0 && n - k >= 0)
  {
    return ((fact[n] * factinv[k]) % MOD * factinv[n - k]) % MOD;
  }
  return 0;
}

long long power(long long x, long long n)
{
  if (n == 0)
  {
    return 1;
  }
  else if (n % 2 == 1)
  {
    return (x * power(x, n - 1)) % MOD;
  }
  else
  {
    long long half = power(x, n / 2);
    return (half * half) % MOD;
  }
}

long long gcd(long long x, long long y)
{
  return y ? gcd(y, x % y) : x;
}

ll N;
ll Q;
ll A[3010];
int X[3010];
int Y[3010];
ll T[3010][3010];
ll t_half[3010];
ll t_half_rev[3010];

void flush()
{
  ll ans = 0;
  for (auto i = 0; i < N; i++)
  {
    for (auto j = i + 1; j < N; j++)
    {
      ans += T[i][j];
      ans %= MOD;
    }
  }
  cout << ans << endl;
}

int main()
{
  init();
  cin >> N >> Q;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < Q; i++)
  {
    cin >> X[i] >> Y[i];
    X[i]--;
    Y[i]--;
  }
  fill(&T[0][0], &T[0][0] + 3010 * 3010, 0);
  ll initial = power(2, Q);
  for (auto i = 0; i < N; i++)
  {
    for (auto j = 0; j < N; j++)
    {
      if (A[i] > A[j])
      {
        T[i][j] = initial;
      }
    }
  }
  ll two_inv = inv[2];
  for (auto i = 0; i < Q; i++)
  {
    int x = X[i];
    int y = Y[i];
    for (auto j = 0; j < N; j++)
    {
      if (j != x && j != y)
      {
        t_half[j] = (T[j][x] + T[j][y]) * two_inv;
        t_half[j] %= MOD;
        t_half_rev[j] = (T[x][j] + T[y][j]) * two_inv;
        t_half_rev[j] %= MOD;
      }
    }
    for (auto j = 0; j < N; j++)
    {
      if (j != x && j != y)
      {
        T[j][x] = t_half[j];
        T[j][y] = t_half[j];
        T[x][j] = t_half_rev[j];
        T[y][j] = t_half_rev[j];
      }
    }
    swap(T[x][y], T[y][x]);
    cerr << "i = " << i << endl;
    for (auto j = 0; j < N; j++)
    {
      for (auto k = 0; k < N; k++)
      {
        cerr << "T[" << j << "][" << k << "] = " << T[j][k] << endl;
      }
    }
  }
  flush();
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 7/5/2020, 5:33:31 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

int main()
{
  int n, m;
  cin >> n >> m;
  vector<int> v(n, 0);
  int res{0};
  for (auto i{0}; i < m; ++i)
  {
    int k;
    cin >> k;
    for (auto j{0}; j < k; ++j)
    {
      int s;
      cin >> s;
      --s;
      v[s] |= 1 << i;
    }
  }
  for (auto i{0}; i < m; ++i)
  {
    int p;
    cin >> p;
    --p;
    res |= 1 << p;
  }
  int ans{0};
  for (auto i{0}; i < 1 << n; ++i)
  {
    int ok{res};
    for (auto j{0}; j < n; ++j)
    {
      if (i >> j & 1)
      {
        ok ^= v[j];
      }
    }
    if (ok == 0)
    {
      ++ans;
    }
  }
  cout << ans << endl;
}
<commit_msg>tried C.cpp to 'C'<commit_after>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 7/5/2020, 5:33:31 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

int main()
{
  int n, m;
  cin >> n >> m;
  vector<int> v(n, 0);
  int res{0};
  for (auto i{0}; i < m; ++i)
  {
    int k;
    cin >> k;
    for (auto j{0}; j < k; ++j)
    {
      int s;
      cin >> s;
      --s;
      v[s] |= 1 << i;
    }
  }
#if DEBUG == 1
  for (auto i{0}; i < n; ++i)
  {
    cerr << "v[" << i << "] = " << v[i] << endl;
  }
#endif
  for (auto i{0}; i < m; ++i)
  {
    int p;
    cin >> p;
    --p;
    res |= 1 << p;
  }
#if DEBUG == 1
  cerr << "res = " << res << endl;
#endif
  int ans{0};
  for (auto i{0}; i < 1 << n; ++i)
  {
    int ok{res};
    for (auto j{0}; j < n; ++j)
    {
      if (i >> j & 1)
      {
        ok ^= v[j];
      }
    }
    if (ok == 0)
    {
      ++ans;
    }
  }
  cout << ans << endl;
}
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/9/2019, 9:16:59 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

/*
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}

void No()
{
  cout << "No" << endl;
  exit(0);
}
*/

/*
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
*/

const ll MOD = 1000000007;

string L;
ll dp[100010][2];

int main()
{
  cin >> L;
  reverse(L.begin(), L.end());
  int N = L.size();
  dp[0][0] = 1;
  for (auto i = 0; i < N; i++)
  {
    dp[i + 1][1] += (3 * dp[i][1]) % MOD;
    dp[i + 1][1] %= MOD;
    if (L[i] == '0')
    {
      dp[i + 1][0] += dp[i][0];
      dp[i + 1][0] %= MOD;
    }
    else
    {
      dp[i + 1][1] += dp[i][0];
      dp[i + 1][1] %= MOD;
      dp[i + 1][0] += (2 * dp[i][0]) % MOD;
      dp[i + 1][0] %= MOD;
    }
  }
  cout << (dp[N][0] + dp[N][1]) % MOD << endl;
}<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1

/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/9/2019, 9:16:59 PM
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

/*
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}

void No()
{
  cout << "No" << endl;
  exit(0);
}
*/

/*
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
*/

const ll MOD = 1000000007;

string L;
ll dp[100010][2];

int main()
{
  cin >> L;
  reverse(L.begin(), L.end());
  int N = L.size();
  dp[0][0] = 1;
  for (auto i = 0; i < N; i++)
  {
    dp[i + 1][1] += (3 * dp[i][1]) % MOD;
    dp[i + 1][1] %= MOD;
    if (L[i] == '0')
    {
      dp[i + 1][0] += dp[i][0];
      dp[i + 1][0] %= MOD;
    }
    else
    {
      dp[i + 1][1] += dp[i][0];
      dp[i + 1][1] %= MOD;
      dp[i + 1][0] += (2 * dp[i][0]) % MOD;
      dp[i + 1][0] %= MOD;
    }
    cerr << "dp[" << i + 1 << "][" << 0 << "] = " << dp[i + 1][0] << endl;
    cerr << "dp[" << i + 1 << "][" << 1 << "] = " << dp[i + 1][1] << endl;
  }
  cout << (dp[N][0] + dp[N][1]) % MOD << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 12/11/2019, 4:20:39 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/optional.hpp> // for C++14
// ----- using directives and manipulations -----
using boost::rational;
using namespace std;
using ll = long long;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

struct Element
{
  int ind;
  ll left, right;
  boost::optional<int> value; // for C++14
  bool operator<(Element const &rhs) const
  {
    return ind < rhs.ind;
  }
};

class Solve
{
  int N, L;
  set<Element> A;

public:
  Solve(int N, int L, vector<int> input) : N{N}, L{L}
  {
    for (auto i = 0; i < N; i++)
    {
      A.insert({i, 1, 1, input[i]});
    }
  }

  ll count()
  {
    ll ans{N};
    while (true)
    {
#if DEBUG == 1
      for (auto const &e : A)
      {
        cout << "A[" << e.ind << "] = (" << (e.value ? to_string(*e.value) : "n") << ", " << e.left << ", " << e.right << ")" << endl;
      }
#endif
      auto M{min_value()};
      if (!M)
      {
        break;
      }
      vector<Element> tmp;
      for (auto const &e : A)
      {
        if (e.value == M)
        {
          tmp.push_back(e);
        }
        else if (!tmp.empty())
        {
          update(ans, tmp);
        }
      }
      if (!tmp.empty())
      {
        update(ans, tmp);
      }
    }
    return ans;
  }

private:
  boost::optional<int> min_value()
  {
    boost::optional<int> ans;
    for (auto const &e : A)
    {
      if (e.value)
      {
        if (ans)
        {
          ch_min(*ans, *e.value);
        }
        else
        {
          ans = e.value;
        }
      }
    }
    return ans;
  }

  void update(ll &ans, vector<Element> &tmp)
  {
    for (auto const &e : tmp)
    {
      A.erase(A.find(e));
    }
    ans += calc(tmp);
    tmp = press(tmp);
    ans -= calc(tmp);
    for (auto &&e : tmp)
    {
      A.insert(move(e));
    }
    tmp.clear();
  }

  ll calc(vector<Element> const &X)
  {
    ll ans{0};
    ll sum_right{0};
    int S{static_cast<int>(X.size())};
    for (auto i = L - 1; i < S; i++)
    {
      sum_right += X[i].right;
    }
    for (auto i = 0; i < S - L + 1; i++)
    {
      ans += X[i].left * sum_right;
      sum_right -= X[i + L - 1].right;
    }
    assert(sum_right == 0);
    return ans;
  }

  vector<Element> press(vector<Element> const &V)
  {
    assert(!V.empty());
    int S{static_cast<int>(V.size())};
    if (S < L)
    {
      return {{V[0].ind, 0, 0, boost::none}};
    }
    int index{V[0].ind};
    int K{*V[0].value + 1};
    vector<Element> ans(S / L);
    for (auto &e : ans)
    {
      e.ind = index++;
      e.value = K;
    }
    for (auto i = L - 1; i < S; i++)
    {
      ans[(i - L + 1) / L].right += V[i].right;
    }
    int mod{S % L};
    for (auto i = 0; i < S - L + 1; i++)
    {
      ans[(i + L - mod - 1) / L].left += V[i].left;
    }
    return ans;
  }
};

int main()
{
  int N, L;
  cin >> N >> L;
  vector<int> A(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  Solve solve(N, L, A);
  cout << solve.count() << endl;
}
<commit_msg>submit F.cpp to 'F - Counting of Subarrays' (agc037) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 12/11/2019, 4:20:39 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/optional.hpp> // for C++14
// ----- using directives and manipulations -----
using boost::rational;
using namespace std;
using ll = long long;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

struct Element
{
  int ind;
  ll left, right;
  boost::optional<int> value; // for C++14
  bool operator<(Element const &rhs) const
  {
    return ind < rhs.ind;
  }
};

class Solve
{
  int N, L;
  set<Element> A;

public:
  Solve(int N, int L, vector<int> input) : N{N}, L{L}
  {
    for (auto i = 0; i < N; i++)
    {
      A.insert({i, 1, 1, input[i]});
    }
  }

  ll count()
  {
    ll ans{N};
    while (true)
    {
#if DEBUG == 1
      for (auto const &e : A)
      {
        cerr << "A[" << e.ind << "] = (" << (e.value ? to_string(*e.value) : "n") << ", " << e.left << ", " << e.right << ")" << endl;
      }
#endif
      auto M{min_value()};
      if (!M)
      {
        break;
      }
      vector<Element> tmp;
      for (auto const &e : A)
      {
        if (e.value == M)
        {
          tmp.push_back(e);
        }
        else if (!tmp.empty())
        {
          update(ans, tmp);
        }
      }
      if (!tmp.empty())
      {
        update(ans, tmp);
      }
    }
    return ans;
  }

private:
  boost::optional<int> min_value()
  {
    boost::optional<int> ans;
    for (auto const &e : A)
    {
      if (e.value)
      {
        if (ans)
        {
          ch_min(*ans, *e.value);
        }
        else
        {
          ans = e.value;
        }
      }
    }
    return ans;
  }

  void update(ll &ans, vector<Element> &tmp)
  {
    for (auto const &e : tmp)
    {
      A.erase(A.find(e));
    }
    ans += calc(tmp);
    tmp = press(tmp);
    ans -= calc(tmp);
    for (auto &&e : tmp)
    {
      A.insert(move(e));
    }
    tmp.clear();
  }

  ll calc(vector<Element> const &X)
  {
    ll ans{0};
    ll sum_right{0};
    int S{static_cast<int>(X.size())};
    for (auto i = L - 1; i < S; i++)
    {
      sum_right += X[i].right;
    }
    for (auto i = 0; i < S - L + 1; i++)
    {
      ans += X[i].left * sum_right;
      sum_right -= X[i + L - 1].right;
    }
    assert(sum_right == 0);
    return ans;
  }

  vector<Element> press(vector<Element> const &V)
  {
    assert(!V.empty());
    int S{static_cast<int>(V.size())};
    if (S < L)
    {
      return {{V[0].ind, 0, 0, boost::none}};
    }
    int index{V[0].ind};
    int K{*V[0].value + 1};
    vector<Element> ans(S / L);
    for (auto &e : ans)
    {
      e.ind = index++;
      e.value = K;
    }
    for (auto i = L - 1; i < S; i++)
    {
      ans[(i - L + 1) / L].right += V[i].right;
    }
    int mod{S % L};
    for (auto i = 0; i < S - L + 1; i++)
    {
      ans[(i + L - mod - 1) / L].left += V[i].left;
    }
    return ans;
  }
};

int main()
{
  int N, L;
  cin >> N >> L;
  vector<int> A(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  Solve solve(N, L, A);
  cout << solve.count() << endl;
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 9/16/2019, 4:20:33 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll make_mask(vector<ll> const &A)
{
  ll ans{0LL};
  for (auto x : A)
  {
    ans ^= x;
  }
  return ans;
}

ll make_maxi(vector<ll> &A, ll mask)
{
  int N = A.size();
  ll rev{(1LL << 61) - 1 - mask};
  ll ans{0};
  int R{0};
  for (auto k = 61; k >= 0; k--)
  {
    if (rev >> k & 1)
    {
      bool pivot{false};
      for (auto i = R; i < N; i++)
      {
        if (A[i] >> k & 1)
        {
          swap(A[i], A[R]);
          pivot = true;
          break;
        }
      }
      if (!pivot)
      {
        continue;
      }
      for (auto i = 0; i < N; i++)
      {
        if (i != R && A[i] >> k & 1)
        {
          A[i] ^= A[R];
        }
      }
      ++R;
    }
  }
  for (auto i = 0; i < R; i++)
  {
    ans ^= A[i];
  }
  return ans;
}

ll calc_ans(ll mask, ll maxi)
{
  return maxi * 2 + mask;
}

int main()
{
  int N;
  cin >> N;
  vector<ll> A(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  ll mask{make_mask(A)};
  ll maxi{make_maxi(A, mask)};
  ll ans{calc_ans(mask, maxi)};
  cout << ans << endl;
}<commit_msg>submit F.cpp to 'F - Xor Sum 3' (abc141) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 9/16/2019, 4:20:33 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll make_mask(vector<ll> const &A)
{
  ll ans{0LL};
  for (auto x : A)
  {
    ans ^= x;
  }
  return ans;
}

ll make_maxi(vector<ll> &A, ll mask)
{
  int N = A.size();
  ll rev{(1LL << 61) - 1 - mask};
  ll ans{0};
  int R{0};
  for (auto k = 61; k >= 0; k--)
  {
    if (rev >> k & 1)
    {
      bool pivot{false};
      for (auto i = R; i < N; i++)
      {
        if (A[i] >> k & 1)
        {
          swap(A[i], A[R]);
          pivot = true;
          break;
        }
      }
      if (!pivot)
      {
        continue;
      }
      for (auto i = 0; i < N; i++)
      {
        if (i != R && A[i] >> k & 1)
        {
          A[i] ^= A[R];
        }
      }
      ++R;
    }
  }
  for (auto i = 0; i < R; i++)
  {
    ans ^= A[i];
  }
  return ans & rev;
}

ll calc_ans(ll mask, ll maxi)
{
  return maxi * 2 + mask;
}

int main()
{
  int N;
  cin >> N;
  vector<ll> A(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  ll mask{make_mask(A)};
  ll maxi{make_maxi(A, mask)};
  ll ans{calc_ans(mask, maxi)};
  cout << ans << endl;
}<|endoftext|>