// #define ONLINE_JUDGE
// Interactive problem solution template
#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <memory>
#include <cmath>
#include <climits>
#include <numeric>
#include <tuple>
#include <random>
#include <memory.h>
#include <stdint.h>
#if !defined(__GNUC__)
#else // !defined(__GNUC__)
#define _CrtDbgBreak() __builtin_trap()
#endif // !defined(__GNUC__)
#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else
#define LOCAL_TEST 1
#endif
template<typename T1, typename T2> auto Endl(std::basic_ostream<T1, T2>& ostr) -> decltype(std::endl<T1, T2>(ostr)) {
return std::endl<T1, T2>(ostr);
}
#if LOCAL_TEST
struct AssertsCounter
{
AssertsCounter(): counter(0) {}
~AssertsCounter() { std::cerr << Endl << "DIAG: " << (counter == 0 ? "OK" : "FAIL!!!") << " Asserts count: " << counter << Endl; }
void Increment() { counter++; }
uint32_t counter;
};
AssertsCounter g_assertsCounter;
#define LOCAL_ASSERT(expr) { if (!(expr)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr << "'" << Endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#define LOCAL_ASSERT_EQ(expr1, expr2) { if ((expr1) != (expr2)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr1 << "' == '" << #expr2 << "' (" << (expr1) << " vs " << (expr2) << "')" << Endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#else
volatile bool isLocalTestEnabled = 0;
#define LOCAL_ASSERT(expr)
#define LOCAL_ASSERT_EQ(expr1, expr2)
#endif
bool g_isLocalPrintEnabled = (bool)(LOCAL_TEST);
#define LOCAL_PRINT() if (!g_isLocalPrintEnabled) { } else std::cerr // << .. << ..
typedef std::string string8_t;
typedef long double ld_t;
typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint8_t> vector_uint8_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<uint32_t> vector_uint32_t;
typedef std::vector<int64_t> vector_int64_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<string8_t> vector_string8_t;
typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<vector_int32_t> vector_2d_int32_t;
typedef std::vector<vector_uint32_t> vector_2d_uint32_t;
typedef std::vector<vector_int64_t> vector_2d_int64_t;
typedef std::vector<vector_uint64_t> vector_2d_uint64_t;
typedef std::set<size_t> set_size_t;
typedef std::set<int32_t> set_int32_t;
typedef std::set<uint32_t> set_uint32_t;
typedef std::set<int64_t> set_int64_t;
typedef std::set<uint64_t> set_uint64_t;
typedef std::set<string8_t> set_string8_t;
typedef std::multiset<size_t> multiset_size_t;
typedef std::multiset<string8_t> multiset_string8_t;
// Auxiliary functions definition
//
template<typename T> void UpdateMin(T& a, const T b) {a = std::min(a, b);}
template<typename T> void UpdateMax(T& a, const T b) {a = std::max(a, b);}
const ld_t Pi = std::atan(1.0L) * 4.0L;
static const ld_t Eps = 1.0e-09;
template<typename T> bool IsEqual(const T a, const T b) { return std::abs(a - b) < Eps; }
template<typename T> bool IsGreater(const T a, const T b) { return a > b + Eps; }
template<typename T> bool IsLess(const T a, const T b) { return a + Eps < b; }
template<typename T> bool IsGreaterEqual(const T a, const T b) { return !IsLess(a, b); }
template<typename T> bool IsLessEqual(const T a, const T b) { return !IsGreater(a, b); }
template<typename T> string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }
template<typename T> T FromStr(const string8_t& str) {T val = {}; std::istringstream istr(str); istr >> val; return val; }
template<typename ContainerType, typename ValueType> bool Contains(const ContainerType& c, const ValueType& v) { return c.find(v) != c.end(); }
uint64_t SafeAdd(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M - b ? a + b : M; }
uint64_t SafeMul(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M / b ? a * b : M; }
template<typename T> std::istream& operator>>(std::istream& ist, std::vector<T>& data)
{
LOCAL_ASSERT(!!ist);
for (size_t i = 0; i < data.size(); i++) { ist >> data[i]; }
return ist;
}
template<typename T> T Read(std::istream& ist)
{
LOCAL_ASSERT(!!ist);
T val; ist >> val; return val;
}
template<typename T> std::ostream& operator<<(std::ostream& ost, const std::vector<T>& data)
{
for (size_t i = 0; i < data.size(); i++) { if (i != 0) { ost << ' '; } ost << data[i]; }
return ost;
}
struct IInteractor {
// TODO: Declare interaction operations here
virtual uint32_t GetSum(const uint32_t i, const uint32_t j) = 0;
};
class OnlineJudgeInteractor : public IInteractor {
std::istream& ist;
std::ostream& ost;
public:
OnlineJudgeInteractor(std::istream& ist, std::ostream& ost): ist(ist), ost(ost) {
}
// TODO: Implement online judje interaction operations here
virtual uint32_t GetSum(const uint32_t i, const uint32_t j) override {
ost << "? " << (i + 1) << " " << (j + 1) << Endl;
uint32_t s;
ist >> s;
return s;
}
};
class LocalTestInteractor : public IInteractor {
const vector_uint32_t values;
std::ostream* const interactorLog;
public:
LocalTestInteractor(const vector_uint32_t& values, std::ostream* const interactorLog)
: values(values)
, interactorLog(interactorLog) {
if (interactorLog) {
// TODO: dump initial information in order to be capable to use it in OnlineJudgeInteractor
(*interactorLog) << values.size() << Endl;
}
}
virtual uint32_t GetSum(const uint32_t i, const uint32_t j) override {
const uint32_t s = values[i] + values[j];
if (interactorLog) {
// TODO: dump answer information in order to be capable to use it in OnlineJudgeInteractor
(*interactorLog) << s << Endl;
}
return s;
}
};
class Solver {
IInteractor& Interactor;
public:
Solver(IInteractor& interactor): Interactor(interactor) {
}
vector_uint32_t GetAnswer(const size_t n) {
// TODO: insert solution implementation here
vector_uint32_t ans(n);
const uint32_t s01 = Interactor.GetSum(0, 1);
const uint32_t s12 = Interactor.GetSum(1, 2);
const uint32_t s20 = Interactor.GetSum(2, 0);
const uint32_t s012 = (s01 + s12 + s20) / 2;
ans[0] = s012 - s12;
ans[1] = s012 - s20;
ans[2] = s012 - s01;
for (uint32_t i = 3; i < n; i++) {
const uint32_t s = Interactor.GetSum(i - 1, i);
ans[i] = s - ans[i - 1];
}
return ans;
}
};
bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode, const bool useLocalTestInteractor, std::ostream* const interactorLog)
{
// TODO: read initial input information, if needed
size_t n;
ist >> n;
if (multipleTestMode && !ist)
return false;
std::unique_ptr<IInteractor> interactor;
if (useLocalTestInteractor) {
if (multipleTestMode && !ist)
return false;
// TODO: read hidden information for interactor
vector_uint32_t a(n);
ist >> a;
if (multipleTestMode && !ist)
return false;
interactor.reset(new LocalTestInteractor(a, interactorLog));
} else {
interactor.reset(new OnlineJudgeInteractor(ist, ost));
}
LOCAL_ASSERT(interactor.get());
//
LOCAL_PRINT() << Endl << "Next test" << Endl;
Solver solver(*interactor);
const vector_uint32_t ans = solver.GetAnswer(n);
// TODO: output answer in a proper form
ost << "! " << ans << Endl;
return multipleTestMode;
}
void RunSolve(std::istream& ist, std::ostream& ost, const bool useLocalTestInteractor, std::ostream* const interactorLog)
{
#if !defined(ONLINE_JUDGE)
const bool multipleTestMode = true;
while(Solve(ist, ost, multipleTestMode, useLocalTestInteractor, interactorLog)) {};
#else
Solve(ist, ost, false, false, nullptr);
#endif
}
int main(int argc, const char *argv[])
{
bool useLocalTestInteractor = false;
if (argc >= 2) {
if (std::string(argv[1]) == "-t") {
useLocalTestInteractor = true;
LOCAL_PRINT() << "Using local interactor" << Endl;
}
}
std::unique_ptr<std::ofstream> interactorLog;
if (useLocalTestInteractor && argc >= 3) {
const char* const logFileName = argv[2];
LOCAL_PRINT() << "Using file '" << logFileName << "' for interactor input log saving" << Endl;
interactorLog.reset(new std::ofstream(logFileName));
}
RunSolve(std::cin, std::cout, useLocalTestInteractor, interactorLog.get());
}