#line 1 "lib/template.hpp" #ifdef TEMPLATE #else #define TEMPLATE # pragma GCC optimize("O3") using namespace std; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using uint=unsigned; using ll=long long; using ull=unsigned long long; using ld=long double; using pii=pair; using pll=pair; using i128=__int128; using u128=unsigned __int128; templateusing vc=vector; templateusing vvc=vc>; templateusing vvvc=vvc>; templateusing smpq=priority_queue,greater>; templateusing bipq=priority_queue; #define rep(i,n) for(ll i=0;i<(ll)(n);i++) #define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++) #define DREP(i,n,m) for(ll i=(n);i>=(m);i--) #define drep(i,n) for(ll i=((n)-1);i>=0;i--) #define rall(x) x.rbegin(),x.rend() #define mp make_pair #define pb push_back #define fi first #define se second #define is insert #define bg begin() #define ed end() #define all(x) x.begin(),x.end() void scan(int&a) { cin >> a; } void scan(ll&a) { cin >> a; } void scan(string&a) { cin >> a; } void scan(char&a) { cin >> a; } void scan(uint&a) { cin >> a; } void scan(ull&a) { cin >> a; } void scan(bool&a) { cin >> a; } void scan(ld&a){ cin>> a;} template void scan(vector&a) { for(auto&x:a) scan(x); } void read() {} template void read(Head&head, Tail&... tail) { scan(head); read(tail...); } #define INT(...) int __VA_ARGS__; read(__VA_ARGS__); #define LL(...) ll __VA_ARGS__; read(__VA_ARGS__); #define ULL(...) ull __VA_ARGS__; read(__VA_ARGS__); #define STR(...) string __VA_ARGS__; read(__VA_ARGS__); #define VC(type, name, ...) vector name(__VA_ARGS__); read(name); #define VVC(type, name, size, ...) vector> name(size, vector(__VA_ARGS__)); read(name); templatevoid print(T a) { cout << a; } template void print(vectora) { for(int i=0;i<(int)a.size();i++){if(i)cout<<" ";print(a[i]);}cout< void PRT(T a) { print(a); cout < void PRT(Head head, Tail ... tail) { print(head); cout << " "; PRT(tail...); return; } template bool chmin(T &x, F y){ if(x>y){ x=y; return true; } return false; } template bool chmax(T &x, F y){ if(x T floor(T a, T b) { return a / b - (a % b && (a ^ b) < 0); } template T ceil(T x, T y) { return floor(x + y - 1, y); } template T bmod(T x, T y) { return x - y * floor(x, y); } template pair divmod(T x, T y) { T q = floor(x, y); return {q, x - q * y}; } void YesNo(bool b){ cout<<(b?"Yes":"No")<stovi(const string&s,const string&S){ vcv(s.size()); rep(i,s.size()){ auto t=S.find(s[i]); assert(t!=string::npos); v[i]=t; } return v; } template T isqrt(T x){ T F=sqrtl(x); while((F+1)*(F+1)<=x)F++; while(F*F>x)F--; return F; } template vvctrans(const vvc&a){ assert(a.size()&&a[0].size()); vvcb(a[0].size(),vc(a.size())); rep(i,a.size())rep(j,a[0].size()){ b[j][i]=a[i][j]; } return b; } template vctrans(const vc&a){ assert(a.size()&&a[0].size()); vcb(a[0].size(),string(a.size(),0)); rep(i,a.size())rep(j,a[0].size()){ b[j][i]=a[i][j]; } return b; } template int popcount(T n){ return __builtin_popcountll(n); } template L sum(vc&a){ return accumulate(all(a),L(0)); } template vcsubset(T S){ vcans; for(T x=S;x>0;x=(x-1)&S)ans.pb(x); ans.pb(0); return ans; } template T max(vc&a){ return *max_element(all(a)); } template T min(vc&a){ return *min_element(all(a)); } #ifndef COMPRESSER_STRUCT #define COMPRESSER_STRUCT template struct Compresser{ vcx; Compresser(int n=0){x.reserve(n);} Compresser(const vc&xs){ x=xs; } void push(T p){built=false;x.pb(p);} bool built=false; void build(){ if(!chmax(built,1))return; sort(all(x)); x.erase(unique(all(x)),x.end()); } int find(T v){ build(); auto itr=lower_bound(all(x),v)-x.begin(); if(itr==x.size()||x[itr]!=v)return -1; return itr; } int find_next(T v){ build(); return lower_bound(all(x),v)-x.begin(); } int size(){ build(); return x.size(); } T operator[](int i)const{ assert(0<=i&&i vc presum(vc &a){ vc ret(a.size()+1); rep(i,a.size())ret[i+1]=ret[i]+a[i]; return ret; } template vc &operator+=(vc &a,F b){ for (auto&v:a)v += b; return a; } template vc &operator-=(vc&a,F b){ for (auto&v:a)v-=b; return a; } template vc &operator*=(vc&a,F b){ for (auto&v:a)v*=b; return a; } template constexpr T POW(T a,T b){ T res=1; while(b){ if(b&1)res*=a; a*=a; b/=2; } return res; } constexpr ll ten(ll a){ return POW(10,a); } templateconstexpr T inf=numeric_limits::max()/2-1; template int tbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)bit_width(y)-1:-1; } template int lbit(T x){ using U=make_unsigned_t; U y=(U)x; return y?(int)countr_zero(y):-1; } template int tbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return -1; if(p>=W-1)return tbit(y); return tbit(y&((U(1)<<(p+1))-1)); } template int lbit(T x,int p){ using U=make_unsigned_t; constexpr int W=numeric_limits::digits; U y=(U)x; if(p<0)return lbit(y); if(p>=W)return -1; return lbit(y&(~U(0)<>(istream&is,i128&x){ string s;is>>s; x=0; int i=0,neg=0; if(s[0]=='-')neg=1,i=1; for(;i<(int)s.size();i++)x=x*10+s[i]-'0'; if(neg)x=-x; return is; } ostream& operator<<(ostream&os,i128 x){ if(x==0)return os<<0; if(x<0)os<<"-"; using u128=__uint128_t; u128 y=x<0?-(u128)x:(u128)x; string s; while(y)s.pb('0'+y%10),y/=10; reverse(all(s)); return os< ostream& operator<<(ostream&os,const pair&p){ return os<<"("< ostream& operator<<(ostream&os,const array&a){ os<<"["; rep(i,N){ if(i)os<<", "; os< ostream& operator<<(ostream&os,const vc&a){ os<<"["; rep(i,a.size()){ if(i)os<<", "; os< ostream& operator<<(ostream&os,const deque&a){ os<<"["; rep(i,a.size()){ if(i)os<<", "; os< ostream& operator<<(ostream&os,const set&s){ os<<"{"; bool f=0; for(auto&x:s){ if(f)os<<", "; f=1; os< ostream& operator<<(ostream&os,const multiset&s){ os<<"{"; bool f=0; for(auto&x:s){ if(f)os<<", "; f=1; os< ostream& operator<<(ostream&os,const unordered_set&s){ os<<"{"; bool f=0; for(auto&x:s){ if(f)os<<", "; f=1; os< ostream& operator<<(ostream&os,const map&m){ os<<"{"; bool f=0; for(auto&x:m){ if(f)os<<", "; f=1; os< ostream& operator<<(ostream&os,const unordered_map&m){ os<<"{"; bool f=0; for(auto&x:m){ if(f)os<<", "; f=1; os< ostream& operator<<(ostream&os,queueq){ vca; while(q.size())a.pb(q.front()),q.pop(); return os< ostream& operator<<(ostream&os,stacks){ vca; while(s.size())a.pb(s.top()),s.pop(); return os< ostream& operator<<(ostream&os,priority_queueq){ vca; while(q.size())a.pb(q.top()),q.pop(); return os< void debug_out(const T&x,const Ts&...xs){ cout<sync_with_stdio(0); #ifdef LOCAL cout<; static value_type op(value_type a,value_type b){ return {a.first*b.first,b.first*a.second+b.second}; } static value_type e(){ return {1,0}; } };*/ template struct Segtree{ using value_type=typename Info::value_type; vcnode; int N; int n; int lg; void update(int i){ assert(0<=i&&i=0); N=N_; n=1; lg=0; while(n Segtree(int N_,F f){ assert(N_>=0); N=N_; n=1; lg=0; while(nvs(n+1);rep(i,n)vs[i]=node[i+n]; vs[n]=val; (*this)=Segtree(N+1,[&](auto i){ if(i>=1)update(i);N++; } } void set(int i,value_type val){ assert(0<=i&&i>=1)update(i); } void apply(int i,value_type val){ assert(0<=i&&i>=1)update(i); } value_type prod(int l,int r){ assert(0<=l&&l<=r&&r<=N); l+=n,r+=n; value_type sml=Info::e(),smr=Info::e(); while(l int max_right(int L,F f){ assert(0<=L&&L<=N); int l=n+L,w=1; value_type ansL=Info::e(); for(;L+w<=N;l>>=1,w<<=1)if(l&1){ if(!f(Info::op(ansL,node[l])))break; ansL=Info::op(ansL,node[l++]); L+=w; } while(l<<=1,w>>=1){ if(L+w<=N&&f(Info::op(ansL,node[l]))){ ansL=Info::op(ansL,node[l++]); L+=w; } } return L; } template int min_left(int R,F f){ assert(0<=R&&R<=N); int r=n+R,w=1; value_type ansR=Info::e(); for(;R-w>=0;r>>=1,w<<=1)if(r&1){ if(!f(Info::op(node[r-1],ansR)))break; ansR=Info::op(node[--r],ansR); R-=w; } while(r<<=1,w>>=1){ if(R-w>=0&&f(Info::op(node[r-1],ansR))){ ansR=Info::op(node[r-1],ansR); R-=w; r--; } } return R; } }; #line 2 "lib/ds/famous.hpp" template struct FamousHasCommute{ static constexpr bool value=false; }; template struct FamousHasCommute{ static constexpr bool value=T::commute; }; template struct Min{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return min(a,b); } static value_type e(){ return inf; } static value_type get(auto a){ return inf; } }; template struct Max{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return max(a,b); } static value_type e(){ return neg_inf; } }; template struct Sum{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return a+b; } static value_type e(){ return 0; } }; template struct Prod{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return a*b; } static value_type e(){ return 1; } }; template struct Merger{ using value_type=tuple; static constexpr bool commute=(FamousHasCommute::value&&...); template static value_type op_impl(value_type a,value_type b,index_sequence){ return value_type{Infos::op(get(a),get(b))...}; } static value_type op(value_type a,value_type b){ return op_impl(a,b,index_sequence_for{}); } static value_type e(){ return value_type{Infos::e()...}; } }; template struct Affine{ using value_type=pair; static value_type op(value_type a,value_type b){ return {a.first*b.first,a.second*b.first+b.second}; } static value_type e(){ return {1,0}; } }; template struct AddMin{ struct Info{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return min(a,b); } static value_type e(){ return numeric_limits::max(); } }; struct Tag{ using lazy_type=Value_type; static constexpr bool commute=true; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ return old_tag+new_tag; } static lazy_type id(){ return 0; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ return node+lz; } }; }; template struct AddMax{ struct Info{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return max(a,b); } static value_type e(){ return numeric_limits::lowest(); } }; struct Tag{ using lazy_type=Value_type; static constexpr bool commute=true; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ return old_tag+new_tag; } static lazy_type id(){ return 0; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ return node+lz; } }; }; template struct AddSum{ struct Info{ using value_type=pair; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return {a.first+b.first,a.second+b.second}; } static value_type e(){ return {0,0}; } }; struct Tag{ using lazy_type=Value_type; static constexpr bool commute=true; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ return old_tag+new_tag; } static lazy_type id(){ return 0; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ return {node.first+node.second*lz,node.second}; } }; }; template struct AssignMin{ struct Info{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return min(a,b); } static value_type e(){ return numeric_limits::max(); } }; struct Tag{ using lazy_type=pair; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ if(new_tag.first)return new_tag; return old_tag; } static lazy_type id(){ return {false,0}; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ if(lz.first)return lz.second; return node; } }; }; template struct AssignMax{ struct Info{ using value_type=Value_type; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return max(a,b); } static value_type e(){ return numeric_limits::lowest(); } }; struct Tag{ using lazy_type=pair; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ if(new_tag.first)return new_tag; return old_tag; } static lazy_type id(){ return {false,0}; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ if(lz.first)return lz.second; return node; } }; }; template struct AssignSum{ struct Info{ using value_type=pair; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return {a.first+b.first,a.second+b.second}; } static value_type e(){ return {0,0}; } }; struct Tag{ using lazy_type=pair; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ if(new_tag.first)return new_tag; return old_tag; } static lazy_type id(){ return {false,0}; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ if(lz.first)return {node.second*lz.second,node.second}; return node; } }; }; template struct AffineSum{ struct Info{ using value_type=pair; static constexpr bool commute=true; static value_type op(value_type a,value_type b){ return {a.first+b.first,a.second+b.second}; } static value_type e(){ return {0,0}; } }; struct Tag{ using lazy_type=pair; static lazy_type Merge(lazy_type old_tag,lazy_type new_tag){ return {new_tag.first*old_tag.first,new_tag.first*old_tag.second+new_tag.second}; } static lazy_type id(){ return {1,0}; } static typename Info::value_type Apply(typename Info::value_type node,lazy_type lz){ return {node.first*lz.first+node.second*lz.second,node.second}; } }; }; template struct Reversed{ using value_type=typename Info::value_type; static constexpr bool commute=FamousHasCommute::value; static value_type op(value_type a,value_type b){ return Info::op(b,a); } static value_type e(){ return Info::e(); } }; template struct MaxK{ using DATA=MaxK; struct T{ Val val; Key key; T&operator+=(Val v){val+=v;return *this;} T&operator-=(Val v){val-=v;return *this;} T operator+(Val v)const{return {val+v,key};} T operator-(Val v)const{return {val-v,key};} friend T operator+(Val v,const T&a){return a+v;} }; array d; MaxK(){d.fill({neg_inf,Key{}});} T&operator[](int i){return d[i];} const T&operator[](int i)const{return d[i];} bool has(Key key,Val val)const{ rep(i,K)if(d[i].val>neg_inf&&d[i].key==key&&d[i].val==val)return true; return false; } int add_element(Key key,Val val){ if(val<=d[K-1].val)return 0; int pos=0; while(pos=val){ if(d[pos].key==key)return 0; pos++; } int end=K-1; REP(i,pos,K)if(d[i].key==key){end=i;break;} DREP(i,end,pos+1)d[i]=d[i-1]; d[pos]={val,key}; return 1; } DATA&merge_data(const DATA&x){ rep(i,K)add_element(x.d[i].key,x.d[i].val); return *this; } DATA&operator+=(Val v){ rep(i,K)if(d[i].val>neg_inf)d[i].val+=v; return *this; } DATA&operator-=(Val v){ rep(i,K)if(d[i].val>neg_inf)d[i].val-=v; return *this; } DATA operator+(Val v)const{return DATA(*this)+=v;} DATA operator-(Val v)const{return DATA(*this)-=v;} friend DATA operator+(Val v,const DATA&a){return a+v;} }; template struct MaxK{ using DATA=MaxK; struct T{ Val val; Key key; T&operator+=(Val v){val+=v;return *this;} T&operator-=(Val v){val-=v;return *this;} T operator+(Val v)const{return {val+v,key};} T operator-(Val v)const{return {val-v,key};} friend T operator+(Val v,const T&a){return a+v;} }; array d; MaxK(){d.fill({neg_inf,Key{}});} T&operator[](int i){return d[i];} const T&operator[](int i)const{return d[i];} bool has(Key key,Val val)const{ return (d[0].val>neg_inf&&d[0].key==key&&d[0].val==val)||(d[1].val>neg_inf&&d[1].key==key&&d[1].val==val); } int add_element(Key key,Val val){ if(val<=d[1].val)return 0; if(key==d[0].key){ if(val>d[0].val){ d[0].val=val; return 1; } return 0; } if(val>d[0].val){ d[1]=d[0]; d[0]={val,key}; }else{ d[1]={val,key}; } return 1; } DATA&merge_data(const DATA&x){ add_element(x.d[0].key,x.d[0].val); add_element(x.d[1].key,x.d[1].val); return *this; } DATA&operator+=(Val v){ if(d[0].val>neg_inf)d[0].val+=v; if(d[1].val>neg_inf)d[1].val+=v; return *this; } DATA&operator-=(Val v){ if(d[0].val>neg_inf)d[0].val-=v; if(d[1].val>neg_inf)d[1].val-=v; return *this; } DATA operator+(Val v)const{return DATA(*this)+=v;} DATA operator-(Val v)const{return DATA(*this)-=v;} friend DATA operator+(Val v,const DATA&a){return a+v;} }; template struct MaxKInfo{ using value_type=MaxK; static value_type op(const value_type&a,const value_type&b){ value_type res(a); return res.merge_data(b); } static value_type e(){return value_type();} }; template struct MinK{ using DATA=MinK; struct T{ Val val; Key key; T&operator+=(Val v){val+=v;return *this;} T&operator-=(Val v){val-=v;return *this;} T operator+(Val v)const{return {val+v,key};} T operator-(Val v)const{return {val-v,key};} friend T operator+(Val v,const T&a){return a+v;} }; array d; MinK(){d.fill({inf,Key{}});} T&operator[](int i){return d[i];} const T&operator[](int i)const{return d[i];} bool has(Key key,Val val)const{ rep(i,K)if(d[i].val=d[K-1].val)return 0; int pos=0; while(pos struct MinK{ using DATA=MinK; struct T{ Val val; Key key; T&operator+=(Val v){val+=v;return *this;} T&operator-=(Val v){val-=v;return *this;} T operator+(Val v)const{return {val+v,key};} T operator-(Val v)const{return {val-v,key};} friend T operator+(Val v,const T&a){return a+v;} }; array d; MinK(){d.fill({inf,Key{}});} T&operator[](int i){return d[i];} const T&operator[](int i)const{return d[i];} bool has(Key key,Val val)const{ return (d[0].val=d[1].val)return 0; if(key==d[0].key){ if(val struct MinKInfo{ using value_type=MinK; static value_type op(const value_type&a,const value_type&b){ value_type res(a); return res.merge_data(b); } static value_type e(){return value_type();} }; #line 4 "A/main.cpp" struct SegTree{ Segtree>seg; int L,R; int N; //[L,R] を占有 SegTree(ll x):L(1),R(1),N(3),seg(3){ seg.set(1,x); } void extend(){ ll n=R-L+1; vcvs(R-L+1);REP(i,L,R+1)vs[i-L]=(seg.node[i+seg.n]); seg=Segtree>(3*n,[&](auto i){ if(i=n*2)return 0ll; return vs[i-n]; }); N=3*n; L=n,R=n*2-1; } void push_back(ll x){ if(R+1==N){ extend(); } seg.set(++R,x); } void push_front(ll x){ if(L==0){ extend(); } seg.set(--L,x); } //x を超えないような [0,i) -> max i ll leftlower(ll x){ if(x<=0)return 0; return min(seg.max_right(L,[&](auto v){ return vgetvs(){ vcres(R-L+1);rep(i,R-L+1)res[i]=seg.node[L+i+seg.n]; return res; } }; void solve(){ LL(n); VC(ll,p,n); VC(ll,a,n); Segtree,inf}>>minseg(n,[&](auto i){ return pii{p[i],i}; }); vcans(n); vcseg(n+1,0); auto dfs=[&](auto&dfs,int l,int r)->int{ if(l==r){ return n; } if(l+1==r){ ans[p[l]-1]=(a[p[l]-1]>=p[l]); seg[l]=(p[l]); return l; } int mid=minseg.prod(l,r).second; int r0=dfs(dfs,l,mid); int r1=dfs(dfs,mid+1,r); a[p[mid]-1]-=p[mid]; if(r0==n||seg[r0].size()> t; while(t--)solve(); }