結果
| 問題 |
No.2447 行列累乗根
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2023-04-02 22:12:57 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,528 bytes |
| コンパイル時間 | 10,949 ms |
| コンパイル使用メモリ | 275,908 KB |
| 最終ジャッジ日時 | 2025-02-11 22:27:31 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | WA * 28 |
ソースコード
#pragma GCC optimize ( "O3" )
#pragma GCC optimize( "unroll-loops" )
#pragma GCC target ( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" )
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define MAIN main
#define TYPE_OF( VAR ) remove_const<remove_reference<decltype( VAR )>::type >::type
#define UNTIE ios_base::sync_with_stdio( false ); cin.tie( nullptr )
#define FOR( VAR , INITIAL , FINAL_PLUS_ONE ) for( TYPE_OF( FINAL_PLUS_ONE ) VAR = INITIAL ; VAR < FINAL_PLUS_ONE ; VAR ++ )
#define QUIT return 0
#define COUT( ANSWER ) cout << ( ANSWER ) << "\n"
#define SET_PRECISION( PRECISION ) cout << fixed << setprecision( PRECISION )
template <typename T>
class TwoByTwoMatrix
{
public:
T m_M00;
T m_M01;
T m_M10;
T m_M11;
public:
inline TwoByTwoMatrix( const T& M00 , const T& M01 , const T& M10 , const T& M11 ) noexcept;
TwoByTwoMatrix<T>& operator=( const TwoByTwoMatrix<T>& mat ) noexcept;
inline TwoByTwoMatrix<T> operator*( const TwoByTwoMatrix<T>& mat );
};
template <typename T> inline TwoByTwoMatrix<T>::TwoByTwoMatrix( const T& M00 , const T& M01 , const T& M10 , const T& M11 ) noexcept : m_M00( M00 ) , m_M01( M01 ) , m_M10( M10 ) , m_M11( M11 ) {}
template <typename T>
TwoByTwoMatrix<T>& TwoByTwoMatrix<T>::operator=( const TwoByTwoMatrix<T>& mat ) noexcept
{
if( &mat != this ){
m_M00 = mat.m_M00;
m_M01 = mat.m_M01;
m_M10 = mat.m_M10;
m_M11 = mat.m_M11;
}
return *this;
}
template <typename T> inline TwoByTwoMatrix<T> TwoByTwoMatrix<T>::operator*( const TwoByTwoMatrix<T>& mat ) { return TwoByTwoMatrix<T>( m_M00 * mat.m_M00 + m_M01 * mat.m_M10 , m_M00 * mat.m_M01 + m_M01 * mat.m_M11 , m_M10 * mat.m_M00 + m_M11 * mat.m_M10 , m_M10 * mat.m_M01 + m_M11 * mat.m_M11 ); }
void stod( const string& s , ll& num , double& answer )
{
bool negative;
uint i_start;
if( s.substr( 0 , 1 ) == "-" ){
negative = true;
i_start = 1;
} else {
negative = false;
i_start = 0;
}
uint size = s.size();
uint exponent = 0;
FOR( i , i_start , size ){
string c = s.substr( i , 1 );
if( c == "." ){
assert( exponent == 0 );
assert( i - i_start == 1 );
exponent = size - 1 - i;
assert( exponent <= 5 );
} else {
num = num * 10 + stoi( c );
}
}
answer = ( negative ? - num : num );
while( exponent != 0 ){
answer *= 0.1;
exponent--;
}
return;
}
int MAIN()
{
UNTIE;
string S;
double M_entry[2][2];
ll num[2][2] = {};
FOR( i , 0 , 2 ){
double ( &Mi )[2] = M_entry[i];
ll ( &numi )[2] = num[i];
FOR( j , 0 , 2 ){
cin >> S;
stod( S , numi[j] , Mi[j] );
}
}
double ( &M0 )[2] = M_entry[0];
double ( &M1 )[2] = M_entry[1];
double& M00 = M0[0];
double& M01 = M0[1];
double& M10 = M1[0];
double& M11 = M1[1];
double tr = M00 + M11;
double det = M00 * M11 - M01 * M10;
double disc = tr * tr - 4.0 * det;
constexpr const double epsilonsq = 0.0000000001;
double discrt = ( disc < epsilonsq ? 0.0 : sqrt( disc ) );
double e[2] = { ( tr + discrt ) / 2.0 , ( tr - discrt ) / 2.0 };
double U_entry[2][2];
double ( &U0 )[2] = U_entry[0];
double ( &U1 )[2] = U_entry[1];
double norm[2];
double normsq;
bool degenerate = false;
constexpr const double epsilon = 0.00001;
FOR( j , 0 , 2 ){
double& ej = e[j];
double& U0j = U0[j];
double& U1j = U1[j];
double& normj = norm[j];
U0j = M10;
U1j = ej - M00;
normsq = U0j * U0j + U1j * U1j;
normj = ( normsq < epsilonsq ? 0.0 : sqrt( normsq ) );
if( normj < epsilon ){
U0j = ej - M11;
U1j = M01;
normsq = U0j * U0j + U1j * U1j;
normj = ( normsq < epsilonsq ? 0.0 : sqrt( normsq ) );
if( normj < epsilon ){
degenerate = true;
break;
}
}
}
double& e0 = e[0];
double& e1 = e[1];
double& U00 = U0[0];
double& U01 = U0[1];
double& U10 = U1[0];
double& U11 = U1[1];
if( degenerate ){
e0 = M11;
e1 = M11;
U00 = 1.0;
U10 = 0.0;
U01 = 0.0;
U11 = 1.0;
} else {
double& norm0 = norm[0];
double& norm1 = norm[1];
U00 /= norm0;
U10 /= norm0;
U01 /= norm1;
U11 /= norm1;
}
TwoByTwoMatrix<double> U{ U00 , U01 , U10 , U11 };
TwoByTwoMatrix<double> Uinv{ U00 , U10 , U01 , U11 };
TwoByTwoMatrix<double> Dcbrt{ cbrt( e0 ) , 0.0 , 0.0 , cbrt( e1 ) };
TwoByTwoMatrix<double> Mcbrt = U * Dcbrt * Uinv;
SET_PRECISION( 5 );
cout << Mcbrt.m_M00 << " " << Mcbrt.m_M01 << "\n";
cout << Mcbrt.m_M10 << " " << Mcbrt.m_M11 << "\n";
QUIT;
}