#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< struct DualSegtree{ using value_type=X::value_type; template struct has_commute{ static constexpr bool value=false; }; template struct has_commute{ static constexpr bool value=T::commute; }; static constexpr bool commute=has_commute::value; vclazy; vcnode; int n; int lg; DualSegtree(int N){ assert(N>=0); lg=0;while((1<(n,X::e()); node=vc(n*2,X::e()); } DualSegtree(int N,const vc&v){ assert(N>=0); lg=0;while((1<(n,X::e()); node=vc(n*2,X::e()); build(v); } void build(const vc&v){ assert((int)v.size()<=n); rep(i,n)node[i+n]=v[i]; } void set(int p,value_type x,bool is_first=false){ assert(0<=p&&p>i); node[p]=x; }else node[p+n]=x; } void all_apply(int k,value_type x){ assert(0<=k&&k>i)<>i); if(((r>>i)<>i); } } while(l>i]); return res; } for(int i=lg;i;i--)push(p>>i); return node[p]; } }; #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" void solve(){ LL(n); VC(ll,a,n); vcxs(n); map>is; ll now=0; rep(i,n){ xs[i]=(now^=a[i]); is[now].pb(i); } DualSegtree>seg(n+1);seg.set(0,1); for(auto&[a,b]:is)seg.set(b[0]+1,0); rep(i,n){ seg.apply(0,n+1,seg.get(i)); auto itr=lower_bound(all(is[xs[i]]),i); if(next(itr)!=is[xs[i]].end()){ seg.set(*next(itr)+1,0); } //rep(j,n+1)dbg(seg.get(j),j); } PRT(seg.get(n)%(ll)(ten(9)+7)); } signed main(){ int t=1; // cin >> t; while(t--)solve(); }