diff --git a/permutation.cc b/permutation.cc index d6456f5..82d2ca1 100644 --- a/permutation.cc +++ b/permutation.cc @@ -72,6 +72,48 @@ for(T i=1; i<=n; ++i) if(used[i]!=1) return 0; return 1; } + + + +//in-place o(n^2) cf. arxiv 1901.01926v2 +//better alg. exists but more complicated +template +void NRPerm::reverse_cycle(int start) +{ +int cur=(*this)[start]; +int prev=start; +while(cur!=start) + { + int next=(*this)[cur]; + (*this)[cur]=prev; + prev=cur; + cur=next; + } +(*this)[start]=prev; +} + + +template +int NRPerm::cycle_leader(int start) const +{ +int cur=(*this)[start]; +int smallest=start; +while(cur!=start) + { + if(cur +void NRPerm::inverseme() +{ +for(int i=1; i<=size(); ++i) if(cycle_leader(i)==i) reverse_cycle(i); +} + + template NRPerm NRPerm::inverse() const { diff --git a/permutation.h b/permutation.h index 01a44ac..f4a4cd4 100644 --- a/permutation.h +++ b/permutation.h @@ -64,6 +64,9 @@ public: bool is_identity() const; CompressedPartition cycles() const {return CyclePerm(*this).cycles(size());}; NRPerm inverse() const; + void reverse_cycle(int i); //aux for inverseme + int cycle_leader(int i) const; //aux for inverseme + void inverseme(); //in-place NRPerm reverse() const; //backward order NRPerm operator&(const NRPerm &rhs) const; //concatenate the permutations this,rhs, renumbering rhs (not commutative) NRPerm operator|(const NRPerm &rhs) const; //concatenate the permutations rhs,this, renumbering rhs (not commutative) diff --git a/t.cc b/t.cc index 322883d..81b5cc3 100644 --- a/t.cc +++ b/t.cc @@ -4788,7 +4788,7 @@ cout<>n; +NRPerm p(n); p.randomize(); +NRPerm q=p.inverse(); +p.inverseme(); +if(p!=q) laerror("inverseme failed"); +else cout <