CSES - Shared codeLink to this code:
https://cses.fi/paste/e0e917d7faed57ac1ae15c/
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define indexed_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
//find_by_order = returns pointer to element at that pos
//order_of_key = returns pos of the given element
#define indexed_multiset tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
#define all(x) (x).begin(),(x).end()
#define mem1(a) memset(a,-1,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
#define int long long
#define endl "\n"
typedef vector<int> vi;
typedef pair<int,int> pi;
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define rep(i,a,b) for (int i = a; i <b; i++)
#define MOD 1000000007
#define boost
#define debug1(x) cout<<#x<<" "<<x<<endl;
#define debug2(x,y) cout<<#x<<" "<<x<<" "<<#y<<" "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" "<<x<<" "<<#y<<" "<<y<<" "<<#z<<" "<<z<<endl;
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.F>>a.S;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.F<<" "<<a.S;return out;}
template<class _T>inline void read(_T &_a)
{
bool f=0; char _c=getchar(); _a=0;
while(_c<'0'||_c>'9'){ if(_c=='-') f=1; _c=getchar(); }
while(_c>='0'&&_c<='9'){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=getchar(); }
if(f) _a=-_a;
}
const long long INF=1e18;
int T;
int mod_pow(int a,int b)
{
if(b==0) return 1;
if(b==1) return a%MOD;
int temp=mod_pow(a,b/2);
if(b%2==0) return (temp*temp)%MOD;
else return (((temp*temp)%MOD)*a)%MOD;
}
int modInverse(int A)
{
return mod_pow(A,MOD-2);
}
__int128_t mod_pow2( __int128_t a, __int128_t b)
{
if(b==0) return 1;
if(b==1) return a%MOD;
__int128_t temp=mod_pow(a,b/2);
if(b%2==0) return (temp*temp)%MOD;
else return (((temp*temp)%MOD)*a)%MOD;
}
int32_t main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin>>n;
map<int,int> mp;
int mn=1;
int l,r;
for(int i=1;i<=n;i++)
{
cin>>l>>r;
mp[l] = r;
mn = (mn%MOD * (mod_pow(l,r)))%MOD;
}
int ans2 = 1;
int ans1 =1;
__int128_t an=1;
for(auto q : mp)
{
ans1 = (ans1%MOD * (q.second+1)%MOD)%MOD;
an = an*(q.second+1);
int temp = ((mod_pow(q.first,q.second+1)-1)*modInverse(q.first-1))%MOD;
temp = temp%MOD;
ans2 = ((ans2%MOD * temp%MOD)%MOD);
}
int ans3 = mod_pow2(mn,an/2);
cout<<ans1<<" "<<ans2<<" "<<ans3<<endl;
// you should actually read the stuff at the bottom
/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
* DON'T GET STUCK ON ONE APPROACH
*/
return 0;
}