#ifndef MYLOCAL //# pragma GCC target("avx2")//yukiではNG # pragma GCC optimize("O3") # pragma GCC optimize("unroll-loops") #endif #if defined(NDEBUG) #undef NDEBUG #endif #include "bits/stdc++.h" using namespace std; using ll=long long; using dd=long double; using pll=pair; using tll=tuple; using qll=tuple; using namespace chrono; constexpr ll INF = 1201001001001001001; struct Fast{ Fast(){ cin.tie(0); ios::sync_with_stdio(false); cout<::max_digits10); } } fast; #define EXPAND( x ) x//VS用おまじない #define overload3(_1,_2,_3,name,...) name #define overload4(_1,_2,_3,_4,name,...) name #define overload5(_1,_2,_3,_4,_5,name,...) name #define rep1(N) for (ll dmyi = 0; dmyi < (N); dmyi++) #define rep2(i, N) for (ll i = 0; i < (N); i++) #define rep3(i, S, E) for (ll i = (S); i <= (E); i++) #define rep4(i, S, E, t) for (ll i = (S); i <= (E); i+=(t)) #define rep(...) EXPAND(overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)) #define dep3(i, E, S) for (ll i = (E); i >= (S); i--) #define dep4(i, E, S, t) for (ll i = (E); i >= (S); i-=(t)) #define dep(...) EXPAND(overload4(__VA_ARGS__, dep4, dep3,_,_)(__VA_ARGS__)) #define ALL1(v) (v).begin(), (v).end() #define ALL2(v,E) (v).begin(), (v).begin()+((E)+1) #define ALL3(v,S,E) (v).begin()+(S), (v).begin()+((E)+1) #define all(...) EXPAND(overload3(__VA_ARGS__, ALL3, ALL2, ALL1)(__VA_ARGS__)) template inline bool chmax(T &a, T b) { if (a < b) { a = b; return true; }return false; } template inline bool chmin(T &a, T b) { if (a > b) { a = b; return true; }return false; } template [[nodiscard]] inline T limithi(T a,T b){ return min(a,b); } template [[nodiscard]] inline T limitlo(T a,T b){ return max(a,b); } template inline bool chlimithi(T &a,T b){ return chmin(a,b); } template inline bool chlimitlo(T &a,T b){ return chmax(a,b); } template inline auto maxe(T &&v,ll S,ll E){ return *max_element(all(v,S,E)); } template inline auto maxe(T &&v){ return *max_element(all(v)); } template inline auto mine(T &&v,ll S,ll E){ return *min_element(all(v,S,E)); } template inline auto mine(T &&v){ return *min_element(all(v)); } template::type::value_type> inline U sum(T &&v,ll S,ll E) {return accumulate(all(v,S,E),U());} template inline auto sum(T &&v) {return sum(v,0,v.end()-v.begin()-1);} template inline ll sz(T &&v){ return (ll)v.size(); } //cin struct cinutil{ template static void cin1core(T &a){ cin>>a; } template static void cin1core(pair &a){ cin1core(a.first),cin1core(a.second); } template static void cin1core(tuple &a){ cinTplRec,sizeof...(Args)-1>()(a); } template static void cin1core(array &a){ for (int i=0; i<(int)N; ++i) cin>>a[i]; } private: template struct cinTplRec{ void operator()(Tpl &a){ cinTplRec()(a); cin1core(get(a)); } }; template struct cinTplRec{ void operator()(Tpl &a){ cin1core(get<0>(a)); } }; }; template T cin1(){ T a; cinutil::cin1core(a); return a; } template tuple cins(){ return cin1>(); } //cout template inline ostream &operator<<(ostream &os,const pair &a){ return os << a.first << ' ' << a.second; } template inline ostream &operator<<(ostream &os,const tuple &a){ return os << get<0>(a) << ' ' << get<1>(a) << ' ' << get<2>(a); } template inline ostream &operator<<(ostream &os,const tuple &a){ return os << get<0>(a) << ' ' << get<1>(a) << ' ' << get<2>(a) << ' ' << get<3>(a); } template inline ostream &operator<<(ostream &os,const vector &a){ for (ll i=0; i<(ll)a.size(); i++) os<<(i>0?" ":"")<(system_clock::now()-st).count()/1000;} } timeget; template struct mll_{ using Int = long long; using ll = long long; ll val_=0; /*---- utility ----*/ mll_ &norm(){ return normR().normS(); }//正規化 mll_ &normR(){ val_%=MOD; return *this; }//剰余正規化のみ mll_ &normS(){ if (val_<0) val_+=MOD; return *this; }//正負正規化のみ mll_ &normP(){ if (val_>=MOD) val_-=MOD; return *this; }//加算時正規化 mll_ &invsg(){ val_=-val_; return normS(); }//正負反転 ll modinv(int a){//a^-1 mod MOD int ypre=0,y=1,apre=MOD; while (a>1){ int t=apre/a; apre-=a*t,swap(a,apre); ypre-=y*t,swap(y,ypre); } return y<0 ? y+MOD : y; } /*---- I/F ----*/ mll_(){} mll_(ll v): val_(v){ norm(); } mll_(ll v,bool b): val_(v){} //正規化無のコンストラクタ Int val()const{ return (Int)val_; } bool isnone() const { return val_==-1; } //true:値なし mll_ &none() { val_=-1; return *this; } //値なしにする mll_ &inv(){ val_=modinv((int)val_); return *this; } mll_ &operator+=(mll_ b){ val_+=b.val_; return normP(); } mll_ &operator-=(mll_ b){ val_-=b.val_; return normS(); } mll_ &operator*=(mll_ b){ val_*=b.val_; return normR(); } mll_ &operator/=(mll_ b){ return *this*=b.inv(); } mll_ &operator+=(ll b){ return *this+=mll_(b); } mll_ &operator-=(ll b){ return *this-=mll_(b); } mll_ &operator*=(ll b){ return *this*=mll_(b); } mll_ &operator/=(ll b){ return *this/=mll_(b); } mll_ operator-()const{ return mll_(*this).invsg(); } mll_ operator+(mll_ b)const{ return mll_(*this)+=b; } mll_ operator-(mll_ b)const{ return mll_(*this)-=b; } mll_ operator*(mll_ b)const{ return mll_(*this)*=b; } mll_ operator/(mll_ b)const{ return mll_(*this)/=b; } mll_ operator+(ll b)const{ return mll_(*this)+=b; } mll_ operator-(ll b)const{ return mll_(*this)-=b; } mll_ operator*(ll b)const{ return mll_(*this)*=b; } mll_ operator/(ll b)const{ return mll_(*this)/=b; } friend mll_ operator+(ll a,mll_ b){ return b+a; } friend mll_ operator-(ll a,mll_ b){ return -b+a; } friend mll_ operator*(ll a,mll_ b){ return b*a; } friend mll_ operator/(ll a,mll_ b){ return mll_(a)/b; } bool operator==(mll_ b)const{ return val_==b.val_; } bool operator!=(mll_ b)const{ return val_!=b.val_; } bool operator==(ll b)const{ return *this==mll_(b); } bool operator!=(ll b)const{ return *this!=mll_(b); } friend bool operator==(ll a,mll_ b){ return mll_(a)==b; } friend bool operator!=(ll a,mll_ b){ return mll_(a)!=b; } friend ostream &operator<<(ostream &os,mll_ a){ return os << a.val_; } friend istream &operator>>(istream &is,mll_ &a){ return is >> a.val_; } mll_ pow(ll k)const{ mll_ ret(1,false),a(*this); for (; k>0; k>>=1,a*=a) if (k&1)ret*=a; return ret; } static constexpr int mod() { return MOD; } //enum{ modll=MOD }; }; template struct Vector: vector{ using Int = long long; using vT=vector; using cvT=const vector; using cT=const T; using vT::vT; //親クラスのコンストラクタの隠蔽を回避 using vT::begin,vT::end,vT::insert,vT::erase; auto it(Int i){ return begin()+i; } auto it(Int i)const{ return begin()+i; } Vector(cvT& b):vT(b){} Vector(vT&& b):vT(move(b)){} Vector(int n,cT& x):vT(n,x){}// ┬ 型推論のためラッパー Vector(long long n,cT& x):vT(n,x){} template Vector(const Vector& b):vT(b.begin(),b.end()){} template Vector(const vector& b):vT(b.begin(),b.end()){} Vector(Int n,T s,T d){ iota(n,s,d); } Vector(Int n,function g):vT(n){ for(Int i=0;i &b){ return *this+=(cvT&)b; } Vector &operator-=(const Vector &b){ return *this-=(cvT&)b; } Vector &operator*=(const Vector &b){ return *this*=(cvT&)b; } Vector &operator/=(const Vector &b){ return *this/=(cvT&)b; } Vector &operator%=(const Vector &b){ return *this%=(cvT&)b; } Vector operator+(cvT &b){ return Vector(*this)+=b; } Vector operator-(cvT &b){ return Vector(*this)-=b; } Vector operator*(cvT &b){ return Vector(*this)*=b; } Vector operator/(cvT &b){ return Vector(*this)/=b; } Vector operator%(cvT &b){ return Vector(*this)%=b; } Vector operator+(const Vector &b){ return Vector(*this)+=b; } Vector operator-(const Vector &b){ return Vector(*this)-=b; } Vector operator*(const Vector &b){ return Vector(*this)*=b; } Vector operator/(const Vector &b){ return Vector(*this)/=b; } Vector operator%(const Vector &b){ return Vector(*this)%=b; } template Vector &operator+=(S x){ for(T &e: *this) e+=x; return *this; } template Vector &operator-=(S x){ for(T &e: *this) e-=x; return *this; } template Vector &operator*=(S x){ for(T &e: *this) e*=x; return *this; } template Vector &operator/=(S x){ for(T &e: *this) e/=x; return *this; } template Vector &operator%=(S x){ for(T &e: *this) e%=x; return *this; } template Vector operator+(S x)const{ return Vector(*this)+=x; } template Vector operator-(S x)const{ return Vector(*this)-=x; } template Vector operator*(S x)const{ return Vector(*this)*=x; } template Vector operator/(S x)const{ return Vector(*this)/=x; } template Vector operator%(S x)const{ return Vector(*this)%=x; } Vector &operator--(int){ return *this-=1; } Vector &operator++(int){ return *this+=1; } Vector operator-()const{ return Vector(*this)*=-1; } template friend Vector operator-(S x,const Vector &a){ return -a+=x; } T& at(Int i){ assert(i>=0); if(n()<=i)vT::resize(i+1); return vT::operator[](i); } Vector slice(Int l,Int r,Int d=1)const{ Vector ret; for(Int i=l;(d>0&&i<=r)||(d<0&&r<=i);i+=d) ret.push_back((*this)[i]); return ret; } Int size()const{ return (Int)vT::size(); } Int n()const{ return size(); } Vector &push_back(cT& x,Int n=1){ for(Int i=0;iinsert(0,x,n); return *this; } Vector &pop_front(Int n=1){ erase(0,n-1); return *this; } T pull_back(){ T x=move(vT::back()); vT::pop_back(); return x; } T pull_front(){ T x=move(vT::front()); erase(0); return x; } Vector &insert(Int i,cT& x,Int n=1){ insert(it(i),n,x); return *this; } Vector &insert(Int i,cvT& b){ insert(it(i),b.begin(),b.end()); return *this; } Vector &erase(Int i){ erase(it(i)); return *this; } Vector &erase(Int l,Int r){ erase(it(l),it(r+1)); return *this; } Vector &erase(const Vector &idxs){ for (Int I=0; In(); copy(it(l),it(r),it(l-I-1));//[l,r)を前にI+1個ずらす } vT::resize(this->n()-idxs.n()); return *this; } Vector &eraseall(cT& x){ return eraseall(0,size()-1,x); } Vector &eraseall(Int l,Int r,cT& x){ erase(remove(it(l),it(r+1),x),it(r+1)); return *this; } template Vector &eraseif(Pr pr){ return eraseif(0,size()-1,pr); } template Vector &eraseif(Int l,Int r,Pr pr){ erase(remove_if(it(l),it(r+1),pr),it(r+1)); return *this; } Vector &concat(cvT &b,Int n=1){ cvT B = (&b==this) ? *this : vT{}; for(int i=0;iinsert(size(),(&b==this)?B:b); return *this; } Vector repeat(Int n){ return Vector{}.concat(*this,n); } Vector &reverse(Int l=0,Int r=-1){ r+=r<0?size():0; std::reverse(it(l),it(r+1)); return *this; } Vector &rotate(Int m){ return rotate(0,size()-1,m); } Vector &rotate(Int l,Int r,Int m){ std::rotate(it(l),it(m),it(r+1)); return *this; } Vector &sort(Int l=0,Int r=-1){ r+=r<0?size():0; std::sort(it(l),it(r+1)); return *this; } Vector &rsort(Int l=0,Int r=-1){ return sort(l,r).reverse(l,r); } template Vector &sort(Pr pr){ return sort(0,size()-1,pr); } template Vector &sort(Int l,Int r,Pr pr){ std::sort(it(l),it(r+1),pr); return *this; } template Vector &sortbykey(Int l=0,Int r=-1){ r+=r<0?size():0; sort(l,r,[](cT &x,cT &y){return get(x)(y);}); return *this; } Vector &uniq(){ erase(unique(begin(),end()),end()); return *this; } Vector &sortq(){ return sort().uniq(); } Vector &fill(cT& x){ return fill(0,size()-1,x); } Vector &fill(Int l,Int r,cT& x){ std::fill(it(l),it(r+1),x); return *this; } Vector ©(Int i,cvT &b,Int n=1){//A[i]スタートでbをn回分コピー for (int t=0; t=size()) return *this; if (i>=0) (*this)[i]=b[j]; i++; } return *this; } template Vector &iota(Int n,T s=0,S d=1){ vT::resize(n); if(n==0) return *this; (*this)[0]=s; for(int i=1;i Int countif(Pr pr)const{ return countif(0,size()-1,pr); } template Int countif(Int l,Int r,Pr pr)const{ return Int(count_if(it(l),it(r+1),pr)); } Int find(cT& x)const{ return find(0,size()-1,x); } Int find(Int l,Int r,cT& x)const{ return Int(std::find(it(l),it(r+1),x)-begin()); } Int rfind(cT& x)const{ return rfind(0,size()-1,x); } Int rfind(Int l,Int r,cT& x)const{ for (int i=r;i>=l;--i) if ((*this)[i]==x) return i; return l-1; } template Int findif(Pr pr)const{ return findif(0,size()-1,pr); } template Int findif(Int l,Int r,Pr pr)const{ return Int(find_if(it(l),it(r+1),pr)-begin()); } Vector findall(cT& x)const{ return findall(0,size()-1,x); } Vector findall(Int l,Int r,cT& x)const{ return findallif(l,r,[&](cT& y){return y==x;}); } template Vector findallif(Pr pr)const{ return findallif(0,size()-1,pr); } template Vector findallif(Int l,Int r,Pr pr)const{ Vector ret; for(Int i=l;i<=r;++i) if(pr((*this)[i])) ret.push_back(i); return ret; } Int flooridx(cT& x)const{ return Int(upper_bound(begin(),end(),x)-begin()-1); } Int ceilidx(cT& x)const{ return Int(lower_bound(begin(),end(),x)-begin()); } Int leftnmof(cT& x)const{ return flooridx(x)+1; } Int rightnmof(cT& x)const{ return size()-ceilidx(x); } bool contains(cT& x)const{ Int i=flooridx(x); return i>=0 && (*this)[i]==x; } template Int flooridx(cT& x,Pr pr)const{ return Int(upper_bound(begin(),end(),x,pr)-begin()-1); } template Int ceilidx(cT& x,Pr pr)const{ return Int(lower_bound(begin(),end(),x,pr)-begin()); } template Int leftnmof(cT& x,Pr pr)const{ return flooridx(x,pr)+1; } template Int rightnmof(cT& x,Pr pr)const{ return size()-ceilidx(x,pr); } template bool contains(cT& x,Pr pr)const{ Int i=flooridx(x,pr); return i>=0 && (*this)[i]==x; } template using VV = Vector>; template using sVV = vector>; template using VVV = Vector>; template using sVVV = vector>; template using VVVV = Vector>; template using sVVVV = vector>; template using VVVVV = Vector>; template using sVVVVV = vector>; auto tostd()const{ return tov(*this); } template static vector tov(const Vector&v){ return v; } template static sVV tov(const VV &v){ sVV ret; for(auto&& e:v) ret.push_back(e); return ret; } template static sVVV tov(const VVV &v){ sVVV ret; for(auto&& e:v) ret.push_back(e.tostd()); return ret; } template static sVVVV tov(const VVVV &v){ sVVVV ret; for(auto&& e:v) ret.push_back(e.tostd()); return ret; } template static sVVVVV tov(const VVVVV &v){ sVVVVV ret; for(auto&& e:v) ret.push_back(e.tostd()); return ret; } }; #if 0 #define MODLL (1000000007LL) #else #define MODLL (998244353LL) #endif using mll = mll_; //using mll = fraction; namespace SolvingSpace{ template using vector = Vector; using vll=vector< ll>; using vmll=vector< mll>; using vdd=vector< dd>; using vvll=vector< vll>; using vvmll=vector< vmll>; using vvdd=vector< vdd>; using vvvll=vector< vvll>; using vvvmll=vector< vvmll>; using vvvdd=vector< vvdd>; using vvvvll=vector; using vvvvmll=vector; using vvvvdd=vector; using vpll=vector< pll>; using vtll=vector< tll>; using vqll=vector< qll>; using vvpll=vector< vpll>; using vvtll=vector< vtll>; using vvqll=vector< vqll>; using vss=vector; template vector cinv(ll nm){ return vector(nm,[](ll i){ (void)i; return cin1(); }); } template vector> cinvv(ll H,ll W){ return vector>(H,[&](ll i){ (void)i; return cinv(W); }); } /*■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■*/ namespace RndSpace{ using Int = long long; using dd = long double; struct rndutil{ mt19937 mt; rndutil(Int seed=0):mt(GetSeed(seed)){} Int val(Int a,Int b){ return mt()%(b-a+1)+a; }//[a,b]の乱数 dd dval(){ return (dd)mt()/(1ll<<32); }//[0,1)の浮動小数点乱数 vector ary(Int n,Int a,Int b){//長さnの配列、要素[a,b]内、重複可 vector v(n); for (Int i=0; ival(a,b); return v; } vector
dary(Int n){//長さnの[0,1)の浮動小数点乱数 vector
v(n); for (Int i=0; idval(); return v; } string str(Int n,char cs,char ce){//長さnのstring、使用文字cs~ce、重複可 string str(n,cs); for (Int i=0; ival(0,ce-cs); return str; } vector sample(Int n,Int a,Int b){//長さnの配列、要素[a,b]内、重複無 Int len=b-a+1; assert(n<=len); vector v(len); iota(v.begin(),v.end(),a); for (Int i=0; ival(i,len-1)]); v.resize(n); return v; } template auto sample(const T &v){//1つ選択 return v[val(0,(Int)v.size()-1)]; } template auto samplepop(T &v){//1つ取り出し(末尾swapし削除) Int i=val(0,(Int)v.size()-1); auto ret=v[i]; v[i]=v.back(); v.pop_back(); return ret; } Int weightedSampleCore(const vector &cm){//重み付き乱択 累積和版 Int randval=val(1,cm.back()); return Int(lower_bound(cm.begin(),cm.end(),randval)-cm.begin()); } Int weightedSample(const vector &pr){//重み付き乱択 vector cm=pr; for (Int i=1; i<(Int)cm.size(); ++i) cm[i]+=cm[i-1]; return weightedSampleCore(cm); } template void shuffle(T &v){//配列や文字列をシャッフル Int n=(Int)v.size(); for (Int i=0; ival(i,n-1)]); } pair range(Int a,Int b,Int m=1){ //[a,b]内閉区間長さm以上 while (true){ Int l=this->val(a,b+1),r=this->val(a,b+1); if (r-l> tree(Int N,bool zeroIndexed=false); vector> graph( Int N,Int M,bool isConnected,bool isDirected,bool zeroIndexed=false); vector> wgraph(Int N,Int M,Int cmin,Int cmax, bool isConnected,bool isDirected,bool zeroIndexed=false); template EDGES GraphCore(Int N,Int M,bool isConnected,bool isDirected,bool zeroIndexed); #endif private: unsigned int GetSeed(Int seed){ if (seed>=0) return (unsigned int)seed; return (unsigned int)chrono::system_clock::now().time_since_epoch().count(); } }; }//namespace using RndSpace::rndutil; rndutil ru; /* rndutil ru; rndutil ru(-1); //seedランダム(時刻使用) - -------- 整数x -------- 区間[a,b] ll x=ru.val(a,b); - -------- 浮動小数点数x -------- [0,1) dd x=ru.dval(); - -------- 整数ベクトルv -------- 長さn,要素の区間[a,b] 配列重複有 vll v=ru.ary(n,a,b); - -------- 整数ベクトルv -------- 長さn,要素の区間[a,b] 配列重複無 vll v=ru.sample(n,a,b); - -------- 浮動小数点ベクトルv -------- 長さn,[0,1) vdd v=ru.dary(n); - -------- 文字列s -------- 長さn,使用文字'a'~'z' string s=ru.str(n,'a','z'); - -------- 乱択 -------- vll,string等から1つ選択 ll x=ru.sample(v); char c=ru.sample(s); - -------- 乱択削除 -------- vll,string等から1つ取り出し(末尾swapし削除) ll x=ru.samplepop(v); - -------- 重み付き乱択 -------- i∈{0,1,…,n-1}を重みwiで選択 ll i=ru.weightedSample(w); ll i=ru.weightedSampleCore(cm); . ↑wの累積和を与えることで高速に - -------- シャッフル -------- vll,string等 ru.shuffle(a); - -------- 範囲[l,r] -------- [l,r]⊆[a,b] 区間長1以上 auto[l,r]=ru.range(a,b); auto[l,r]=ru.range(a,b,m); . ↑区間長m以上 */ template ll modpow(ll a,ll x,ll M){ ll r=1; for (; x>0; x>>=1,a=T(a)*a%M) if (x&1) r=T(r)*a%M; return r; } /* - ---- a^x mod M ---- ll b=modpow (a,x,M); //a と M が31bit以下のとき ll b=modpow(a,x,M); //a or M が32bit以上のとき */ //#define RANDOM_TEST #if defined(_MSC_VER) #include #endif struct judgeSimulator{ ll queryCount; ll queryCountMax; #if defined(RANDOM_TEST) //----------------------- シミュレート時 ----------------------- //↓↓ジャッジ側データ (cinで得るもの、interactiveでの隠しデータ等) ll N; vll A; vll B; //↑↑ auto cinall(){ //↓↓ジャッジ側データを返すだけ return make_tuple(0/*N,Q,lr*/); } auto query(ll i,ll j,ll k/*ll l,ll r*/){ assert(++queryCount<=queryCountMax); //クエリ回数上限check //↓↓ジャッジ側データを用いてクエリに答える を書く ll sm=A[i%N]+A[j%N]; ll x=modpow (sm,k,N); return B[x]; //↑↑ } void result(auto ans){ //↓↓ansが合っているか判定 を書く ll ansGT=B[1]; bool isCorrect= ans==ansGT; //↑↑ //ansの表示 auto coutans=[&](auto ans){ cout << ans << '\n'; }; coutans(ans); #if 1 //ansGTの表示(ある場合) cout << "- - - - -\n"; coutans(ansGT); cout << "================\n"; #endif if (isCorrect){ //ansが正しいとき ; } else{ //ansが間違っているとき 2周目でデバグ可能 //ここにブレークポイントをセットすると便利 cout << "NG! Press any key to continue..." << endl; #if defined(_MSC_VER) (void)_getch(); #endif } } #else //----------------------- 通常時 ----------------------- auto cinall(){ this->queryCount=0; ////////↓↓cin類を書く ////////↑↑ this->queryCountMax=1600; //クエリ回数上限 return make_tuple(0/*N,Q,lr*/); } auto query(ll i,ll j,ll k/*ll l,ll r*/){ assert(++queryCount<=queryCountMax); //クエリ回数上限check //cout cout << "? "; cout << vll{i,j,k}; cout << endl; //cin auto Bx=cin1(); assert(Bx!=-1); return Bx; } void result(ll ans){//snippet化する cout << "! "; cout << ans; cout << endl; } #endif ll rem(){ return this->queryCountMax - this->queryCount; } }; judgeSimulator simu; void cin2solve() { ru.mt=mt19937(0); simu.cinall();//dmy /* - Ai=yをランダムに選ぶ - 周期を推定 - 現在までに見つかった周期Tとする - y^(30+T),y^(30+2T),…,y^(30+zT),…から、y^30と一致するもの探す →それが新周期T' - 推定したT'でx=y^T'を得る 以上を繰り返してxをサンプリング 多いものが1だが、ほぼ同数もう1つある可能性有 2p^eのとき 1でない方は、yを2倍しても結果が変わらないので区別がつく */ #if defined(_MSC_VER) ll M=708; #else ll M=708; #endif auto estimateT=[&](ll T,ll i)->pll{ // クエリ切れ map bak;//mp[base+j*T]=bx; map mp;//mp[bx]=j ll base= (T>=30) ? T : 30; auto insert=[&](ll j,ll bx){ mp[bx]=j; bak[base+j*T]=bx; }; auto makeretvalues=[&](ll j){ ll retbx=-1; if (bak.contains(j*T)) retbx=bak[j*T]; else{ if (simu.rem()<=2) return -INF; retbx=simu.query(i,0,j*T); } return retbx; }; if (simu.rem()<=2) return pll(-INF,-INF); ll Bx0=simu.query(i,0,base); insert(0,Bx0); //baby rep(j,1,M-1){ if (simu.rem()<=2) return pll(-INF,-INF); ll Bx=simu.query(i,0,base+j*T); if (Bx0==Bx){//見つかった return {j*T,makeretvalues(j)}; } insert(j,Bx); } //giant rep(jj,1,M-1){ ll j=jj*M; if (simu.rem()<=2) return pll(-INF,-INF); ll Bx=simu.query(i,0,base+j*T); //mpにあるか auto it=mp.find(Bx); if (it!=mp.end()){//見つかった auto [bx,jjj]=*it; ll retj=j-jjj; return {retj*T,makeretvalues(retj)}; } bak[base+j*T]=Bx; } assert(false); return pll(); }; map bs; ll T=2; while (true){ ll i=ru.val(1,1000000000); //ll newT=estimateT(T,i); //ll Bx=simu.query(i,0,newT); auto[newT,Bx]=estimateT(T,i); if (Bx==-INF)break; bs[Bx].push_back(i); T=newT; } vtll bf; for (auto&&[Bx,vec]:bs){ bf.emplace_back(sz(vec),vec[0],Bx); } bf.rsort(); if (sz(bf)==1){ auto [ct0,i0,bx0]=bf[0]; simu.result(bx0); } else{//上位2位を見る auto [ct0,i0,bx0]=bf[0]; auto [ct1,i1,bx1]=bf[1]; if (T<30) T*=30; ll dbx0=simu.query(i0,i0,T); ll dbx1=simu.query(i1,i1,T); if (dbx0==bx0 and dbx1==bx1){//両方変化なし→N奇数→1位採用 simu.result(bx0); } else{//変化する方が1 if (dbx0!=bx0) simu.result(bx0); else simu.result(bx1); } } return; } #if defined(RANDOM_TEST) void generand(){ rndutil ru; rep(q,0,INF){ /* 乱数による入力の生成を書く */ ru.mt=mt19937(q); ll N=ru.val(2,1000000); //vll A(N,0,1); vll A(N-1,1,1); ru.shuffle(A); A.push_front(0); vll B(N,0,1); //simuにコピー auto simuclear=[&](){ //0-indexedにするのを忘れずに simu.N=N; simu.A=A; simu.B=B; simu.queryCount=0; simu.queryCountMax=1600; //クエリ回数上限 }; simuclear(); cin2solve(); simuclear();//インタラクティブデバグ用に2回動かす cin2solve(); } } #endif }//SolvingSpace ////////////////////////////////////////// int main(){ #if defined(RANDOM_TEST) //SolvingSpace::cin2solve(); SolvingSpace::generand(); #else #if 0 //SolvingSpace::labo();' SolvingSpace::cin2solve(); #else ll t; cin >> t; rep(i,0,t-1){ SolvingSpace::cin2solve(); } #endif #endif cerr << timeget() <<"ms"<< '\n'; return 0; }