Created
October 9, 2012 07:34
-
-
Save wweic/3857190 to your computer and use it in GitHub Desktop.
Code template for programming contest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <list> | |
#include <map> | |
#include <set> | |
#include <deque> | |
#include <queue> | |
#include <stack> | |
#include <bitset> | |
#include <algorithm> | |
#include <functional> | |
#include <numeric> | |
#include <utility> | |
#include <sstream> | |
#include <iostream> | |
#include <iomanip> | |
#include <cstdio> | |
#include <cmath> | |
#include <cstdlib> | |
#include <cctype> | |
#include <string> | |
#include <cstring> | |
#include <cstdio> | |
#include <cmath> | |
#include <cstdlib> | |
#include <ctime> | |
using namespace std; | |
#define SIZE(X) ((int)(X.size()))//NOTES:SIZE( | |
#define LENGTH(X) ((int)(X.length()))//NOTES:LENGTH( | |
#define MP(X,Y) make_pair(X,Y)//NOTES:MP( | |
typedef long long int64;//NOTES:int64 | |
typedef unsigned long long uint64;//NOTES:uint64 | |
#define two(X) (1<<(X))//NOTES:two( | |
#define twoL(X) (((int64)(1))<<(X))//NOTES:twoL( | |
#define contain(S,X) (((S)&two(X))!=0)//NOTES:contain( | |
#define containL(S,X) (((S)&twoL(X))!=0)//NOTES:containL( | |
const double pi=acos(-1.0);//NOTES:pi | |
const double eps=1e-11;//NOTES:eps | |
template<class T> inline void checkmin(T &a,T b){if(b<a) a=b;}//NOTES:checkmin( | |
template<class T> inline void checkmax(T &a,T b){if(b>a) a=b;}//NOTES:checkmax( | |
template<class T> inline T sqr(T x){return x*x;}//NOTES:sqr | |
typedef pair<int,int> ipair;//NOTES:ipair | |
template<class T> inline T lowbit(T n){return (n^(n-1))&n;}//NOTES:lowbit( | |
template<class T> inline int countbit(T n){return (n==0)?0:(1+countbit(n&(n-1)));}//NOTES:countbit( | |
//Numberic Functions | |
template<class T> inline T gcd(T a,T b)//NOTES:gcd( | |
{if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);} | |
template<class T> inline T lcm(T a,T b)//NOTES:lcm( | |
{if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));} | |
template<class T> inline T euclide(T a,T b,T &x,T &y)//NOTES:euclide( | |
{if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;} | |
if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;} | |
if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}} | |
template<class T> inline vector<pair<T,int> > factorize(T n)//NOTES:factorize( | |
{vector<pair<T,int> > R;for (T i=2;n>1;){if (n%i==0){int C=0;for (;n%i==0;C++,n/=i);R.push_back(make_pair(i,C));} | |
i++;if (i>n/i) i=n;}if (n>1) R.push_back(make_pair(n,1));return R;} | |
template<class T> inline bool isPrimeNumber(T n)//NOTES:isPrimeNumber( | |
{if(n<=1)return false;for (T i=2;i*i<=n;i++) if (n%i==0) return false;return true;} | |
template<class T> inline T eularFunction(T n)//NOTES:eularFunction( | |
{vector<pair<T,int> > R=factorize(n);T r=n;for (int i=0;i<R.size();i++)r=r/R[i].first*(R[i].first-1);return r;} | |
//Matrix Operations | |
const int MaxMatrixSize=40;//NOTES:MaxMatrixSize | |
template<class T> inline void showMatrix(int n,T A[MaxMatrixSize][MaxMatrixSize])//NOTES:showMatrix( | |
{for (int i=0;i<n;i++){for (int j=0;j<n;j++)cout<<A[i][j];cout<<endl;}} | |
template<class T> inline T checkMod(T n,T m) {return (n%m+m)%m;}//NOTES:checkMod( | |
template<class T> inline void identityMatrix(int n,T A[MaxMatrixSize][MaxMatrixSize])//NOTES:identityMatrix( | |
{for (int i=0;i<n;i++) for (int j=0;j<n;j++) A[i][j]=(i==j)?1:0;} | |
template<class T> inline void addMatrix(int n,T C[MaxMatrixSize][MaxMatrixSize],T A[MaxMatrixSize][MaxMatrixSize],T B[MaxMatrixSize][MaxMatrixSize])//NOTES:addMatrix( | |
{for (int i=0;i<n;i++) for (int j=0;j<n;j++) C[i][j]=A[i][j]+B[i][j];} | |
template<class T> inline void subMatrix(int n,T C[MaxMatrixSize][MaxMatrixSize],T A[MaxMatrixSize][MaxMatrixSize],T B[MaxMatrixSize][MaxMatrixSize])//NOTES:subMatrix( | |
{for (int i=0;i<n;i++) for (int j=0;j<n;j++) C[i][j]=A[i][j]-B[i][j];} | |
template<class T> inline void mulMatrix(int n,T C[MaxMatrixSize][MaxMatrixSize],T _A[MaxMatrixSize][MaxMatrixSize],T _B[MaxMatrixSize][MaxMatrixSize])//NOTES:mulMatrix( | |
{ T A[MaxMatrixSize][MaxMatrixSize],B[MaxMatrixSize][MaxMatrixSize]; | |
for (int i=0;i<n;i++) for (int j=0;j<n;j++) A[i][j]=_A[i][j],B[i][j]=_B[i][j],C[i][j]=0; | |
for (int i=0;i<n;i++) for (int j=0;j<n;j++) for (int k=0;k<n;k++) C[i][j]+=A[i][k]*B[k][j];} | |
template<class T> inline void addModMatrix(int n,T m,T C[MaxMatrixSize][MaxMatrixSize],T A[MaxMatrixSize][MaxMatrixSize],T B[MaxMatrixSize][MaxMatrixSize])//NOTES:addModMatrix( | |
{for (int i=0;i<n;i++) for (int j=0;j<n;j++) C[i][j]=checkMod(A[i][j]+B[i][j],m);} | |
template<class T> inline void subModMatrix(int n,T m,T C[MaxMatrixSize][MaxMatrixSize],T A[MaxMatrixSize][MaxMatrixSize],T B[MaxMatrixSize][MaxMatrixSize])//NOTES:subModMatrix( | |
{for (int i=0;i<n;i++) for (int j=0;j<n;j++) C[i][j]=checkMod(A[i][j]-B[i][j],m);} | |
template<class T> inline T multiplyMod(T a,T b,T m) {return (T)((((int64)(a)*(int64)(b)%(int64)(m))+(int64)(m))%(int64)(m));}//NOTES:multiplyMod( | |
template<class T> inline void mulModMatrix(int n,T m,T C[MaxMatrixSize][MaxMatrixSize],T _A[MaxMatrixSize][MaxMatrixSize],T _B[MaxMatrixSize][MaxMatrixSize])//NOTES:mulModMatrix( | |
{ T A[MaxMatrixSize][MaxMatrixSize],B[MaxMatrixSize][MaxMatrixSize]; | |
for (int i=0;i<n;i++) for (int j=0;j<n;j++) A[i][j]=_A[i][j],B[i][j]=_B[i][j],C[i][j]=0; | |
for (int i=0;i<n;i++) for (int j=0;j<n;j++) for (int k=0;k<n;k++) C[i][j]=(C[i][j]+multiplyMod(A[i][k],B[k][j],m))%m;} | |
template<class T> inline T powerMod(T p,int e,T m)//NOTES:powerMod( | |
{if(e==0)return 1%m;else if(e%2==0){T t=powerMod(p,e/2,m);return multiplyMod(t,t,m);}else return multiplyMod(powerMod(p,e-1,m),p,m);} | |
//Point&Line | |
double dist(double x1,double y1,double x2,double y2){return sqrt(sqr(x1-x2)+sqr(y1-y2));}//NOTES:dist( | |
double distR(double x1,double y1,double x2,double y2){return sqr(x1-x2)+sqr(y1-y2);}//NOTES:distR( | |
template<class T> T cross(T x0,T y0,T x1,T y1,T x2,T y2){return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);}//NOTES:cross( | |
int crossOper(double x0,double y0,double x1,double y1,double x2,double y2)//NOTES:crossOper( | |
{double t=(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);if (fabs(t)<=eps) return 0;return (t<0)?-1:1;} | |
bool isIntersect(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)//NOTES:isIntersect( | |
{return crossOper(x1,y1,x2,y2,x3,y3)*crossOper(x1,y1,x2,y2,x4,y4)<0 && crossOper(x3,y3,x4,y4,x1,y1)*crossOper(x3,y3,x4,y4,x2,y2)<0;} | |
bool isMiddle(double s,double m,double t){return fabs(s-m)<=eps || fabs(t-m)<=eps || (s<m)!=(t<m);}//NOTES:isMiddle( | |
//Translator | |
bool isUpperCase(char c){return c>='A' && c<='Z';}//NOTES:isUpperCase( | |
bool isLowerCase(char c){return c>='a' && c<='z';}//NOTES:isLowerCase( | |
bool isLetter(char c){return c>='A' && c<='Z' || c>='a' && c<='z';}//NOTES:isLetter( | |
bool isDigit(char c){return c>='0' && c<='9';}//NOTES:isDigit( | |
char toLowerCase(char c){return (isUpperCase(c))?(c+32):c;}//NOTES:toLowerCase( | |
char toUpperCase(char c){return (isLowerCase(c))?(c-32):c;}//NOTES:toUpperCase( | |
template<class T> string toString(T n){ostringstream ost;ost<<n;ost.flush();return ost.str();}//NOTES:toString( | |
int toInt(string s){int r=0;istringstream sin(s);sin>>r;return r;}//NOTES:toInt( | |
int64 toInt64(string s){int64 r=0;istringstream sin(s);sin>>r;return r;}//NOTES:toInt64( | |
double toDouble(string s){double r=0;istringstream sin(s);sin>>r;return r;}//NOTES:toDouble( | |
template<class T> void stoa(string s,int &n,T A[]){n=0;istringstream sin(s);for(T v;sin>>v;A[n++]=v);}//NOTES:stoa( | |
template<class T> void atos(int n,T A[],string &s){ostringstream sout;for(int i=0;i<n;i++){if(i>0)sout<<' ';sout<<A[i];}s=sout.str();}//NOTES:atos( | |
template<class T> void atov(int n,T A[],vector<T> &vi){vi.clear();for (int i=0;i<n;i++) vi.push_back(A[i]);}//NOTES:atov( | |
template<class T> void vtoa(vector<T> vi,int &n,T A[]){n=vi.size();for (int i=0;i<n;i++)A[i]=vi[i];}//NOTES:vtoa( | |
template<class T> void stov(string s,vector<T> &vi){vi.clear();istringstream sin(s);for(T v;sin>>v;vi.push_bakc(v));}//NOTES:stov( | |
template<class T> void vtos(vector<T> vi,string &s){ostringstream sout;for (int i=0;i<vi.size();i++){if(i>0)sout<<' ';sout<<vi[i];}s=sout.str();}//NOTES:vtos( | |
//Fraction | |
template<class T> struct Fraction{T a,b;Fraction(T a=0,T b=1);string toString();};//NOTES:Fraction | |
template<class T> Fraction<T>::Fraction(T a,T b){T d=gcd(a,b);a/=d;b/=d;if (b<0) a=-a,b=-b;this->a=a;this->b=b;} | |
template<class T> string Fraction<T>::toString(){ostringstream sout;sout<<a<<"/"<<b;return sout.str();} | |
template<class T> Fraction<T> operator+(Fraction<T> p,Fraction<T> q){return Fraction<T>(p.a*q.b+q.a*p.b,p.b*q.b);} | |
template<class T> Fraction<T> operator-(Fraction<T> p,Fraction<T> q){return Fraction<T>(p.a*q.b-q.a*p.b,p.b*q.b);} | |
template<class T> Fraction<T> operator*(Fraction<T> p,Fraction<T> q){return Fraction<T>(p.a*q.a,p.b*q.b);} | |
template<class T> Fraction<T> operator/(Fraction<T> p,Fraction<T> q){return Fraction<T>(p.a*q.b,p.b*q.a);} | |
const int maxlength=200; | |
class bigint | |
{ | |
public: | |
int oper,length,a[maxlength]; | |
bigint(int=0); | |
~bigint(); | |
int max(int a,int b); | |
void check(); | |
void operator=(bigint m); | |
void operator=(int m); | |
void operator=(char *s); | |
bool operator<(bigint m); | |
bool operator<=(bigint m); | |
bool operator>(bigint m); | |
bool operator>=(bigint m); | |
bool operator==(bigint m); | |
bool operator!=(bigint m); | |
bigint operator-(); | |
bigint operator+(bigint m); | |
void operator+=(bigint m); | |
bigint operator-(bigint m); | |
void operator-=(bigint m); | |
bigint operator*(bigint m); | |
bigint operator*(int m); | |
void operator*=(bigint m); | |
void operator*=(int m); | |
bigint operator/(bigint m); | |
bigint operator/(int m); | |
void operator/=(bigint m); | |
void operator/=(int m); | |
bigint operator%(bigint m); | |
bigint operator%(int m); | |
void operator%=(bigint m); | |
void operator%=(int m); | |
}; | |
bigint abs(bigint m); | |
bool read(bigint &m); | |
void write(bigint m); | |
void swrite(char *s,bigint m); | |
void writeln(bigint m); | |
bigint sqr(bigint m); | |
bigint sqrt(bigint m); | |
bigint gcd(bigint a,bigint b); | |
bigint lcm(bigint a,bigint b); | |
int bigint::max(int a,int b) | |
{ | |
return (a>b)?a:b; | |
} | |
bigint::bigint(int v) | |
{ | |
(*this)=v; | |
this->check(); | |
} | |
bigint::~bigint() | |
{ | |
} | |
void bigint::check() | |
{ | |
for (;length>0 && a[length]==0;length--); | |
if (length==0) | |
oper=1; | |
} | |
void bigint::operator=(bigint m) | |
{ | |
oper=m.oper; | |
length=m.length; | |
memcpy(a,m.a,maxlength*sizeof(int)); | |
this->check(); | |
} | |
void bigint::operator=(int m) | |
{ | |
oper=(m>0)?1:-1; | |
m=abs(m); | |
memset(a,0,maxlength*sizeof(int)); | |
for (length=0;m>0;m=m/10000) | |
a[++length]=m%10000; | |
this->check(); | |
} | |
void bigint::operator=(char *s) | |
{ | |
int i,L; | |
(*this)=0; | |
if (s[0]=='-' || s[0]=='+') | |
{ | |
if (s[0]=='-') | |
oper=-1; | |
L=strlen(s); | |
for (i=0;i<L;i++) | |
s[i]=s[i+1]; | |
} | |
L=strlen(s); | |
length=(L+3)/4; | |
for (i=0;i<L;i++) | |
a[(L-i+3)/4]=a[(L-i+3)/4]*10+(s[i]-48); | |
this->check(); | |
} | |
bool bigint::operator<(bigint m) | |
{ | |
if (oper!=m.oper) | |
return oper<m.oper; | |
if (length!=m.length) | |
return oper*length<m.length*oper; | |
for (int i=length;i>=1;i--) | |
if (a[i]!=m.a[i]) | |
return a[i]*oper<m.a[i]*oper; | |
return false; | |
} | |
bool bigint::operator<=(bigint m) | |
{ | |
return !(m<(*this)); | |
} | |
bool bigint::operator>(bigint m) | |
{ | |
return m<(*this); | |
} | |
bool bigint::operator>=(bigint m) | |
{ | |
return !((*this)<m); | |
} | |
bool bigint::operator==(bigint m) | |
{ | |
return (!((*this)<m)) && (!(m<(*this))); | |
} | |
bool bigint::operator!=(bigint m) | |
{ | |
return ((*this)<m) || (m<(*this)); | |
} | |
bigint bigint::operator-() | |
{ | |
bigint c=(*this); | |
c.oper=-c.oper; | |
c.check(); | |
return c; | |
} | |
bigint abs(bigint m) | |
{ | |
bigint c=m; | |
c.oper=abs(c.oper); | |
c.check(); | |
return c; | |
} | |
bigint bigint::operator+(bigint m) | |
{ | |
if (m.length==0) | |
return (*this); | |
if (length==0) | |
return m; | |
if (oper==m.oper) | |
{ | |
bigint c; | |
c.oper=oper; | |
c.length=max(length,m.length)+1; | |
for (int i=1,temp=0;i<=c.length;i++) | |
c.a[i]=(temp=(temp/10000+a[i]+m.a[i]))%10000; | |
c.check(); | |
return c; | |
} | |
return (*this)-(-m); | |
} | |
bigint bigint::operator-(bigint m) | |
{ | |
if (m.length==0) | |
return (*this); | |
if (length==0) | |
return (-m); | |
if (oper==m.oper) | |
{ | |
bigint c; | |
if (abs(*this)>=abs(m)) | |
{ | |
c.oper=oper; | |
c.length=length; | |
for (int i=1,temp=0;i<=length;i++) | |
c.a[i]=((temp=(-int(temp<0)+a[i]-m.a[i]))+10000)%10000; | |
c.check(); | |
return c; | |
} | |
return -(m-(*this)); | |
} | |
return (*this)+(-m); | |
} | |
bool read(bigint &m) | |
{ | |
char s[maxlength*4+10]; | |
if (scanf("%s",&s)==-1) | |
return false; | |
for (int i=0;s[i];i++) | |
if (!((s[i]>='0' && s[i]<='9') || ((s[i]=='+' || s[i]=='-') && i==0))) | |
return false; | |
m=s; | |
return true; | |
} | |
void swrite(char *s,bigint m) | |
{ | |
int L=0; | |
if (m.oper==-1) | |
s[L++]='-'; | |
sprintf(s+L,"%d",m.a[m.length]); | |
for (;s[L]!=0;L++); | |
for (int i=m.length-1;i>=1;i--) | |
{ | |
sprintf(s+L,"%04d",m.a[i]); | |
L+=4; | |
} | |
s[L]=0; | |
} | |
void write(bigint m) | |
{ | |
if (m.oper==-1) | |
printf("-"); | |
printf("%d",m.a[m.length]); | |
for (int i=m.length-1;i>=1;i--) | |
printf("%04d",m.a[i]); | |
} | |
void writeln(bigint m) | |
{ | |
write(m); | |
printf("\n"); | |
} | |
bigint bigint::operator*(bigint m) | |
{ | |
bigint c; | |
c.oper=oper*m.oper; | |
c.length=length+m.length; | |
for (int i=1;i<=m.length;i++) | |
{ | |
int number=m.a[i],j,temp=0; | |
for (j=1;j<=length;j++) | |
c.a[i+j-1]+=number*a[j]; | |
if (i%10==0 || i==m.length) | |
for (j=1;j<=c.length;j++) | |
c.a[j]=(temp=(temp/10000)+c.a[j])%10000; | |
} | |
c.check(); | |
return c; | |
} | |
bigint bigint::operator*(int m) | |
{ | |
if (m<0) | |
return -((*this)*(-m)); | |
if (m>100000) | |
return (*this)*bigint(m); | |
bigint c; | |
c.length=length+2; | |
c.oper=oper; | |
int t=0; | |
for (int i=1;i<=c.length;i++) | |
c.a[i]=(t=(t/10000+a[i]*m))%10000; | |
c.check(); | |
return c; | |
} | |
bigint bigint::operator/(bigint m) | |
{ | |
if (m.length==0) | |
{ | |
printf("Division by zero.\n"); | |
exit(0); | |
} | |
if (abs(*this)<abs(m)) | |
return 0; | |
bigint c,left; | |
c.oper=oper/m.oper; | |
m.oper=1; | |
c.length=length-m.length+1; | |
left.length=m.length-1; | |
memcpy(left.a+1,a+length-left.length+1,left.length*sizeof(int)); | |
for (int i=c.length;i>=1;i--) | |
{ | |
left=left*10000+a[i]; | |
int head=0,tail=10000,mid; | |
while (head+1<tail) | |
{ | |
mid=(head+tail)/2; | |
if (m*mid<=left) | |
head=mid; | |
else | |
tail=mid; | |
} | |
c.a[i]=head; | |
left-=m*head; | |
} | |
c.check(); | |
return c; | |
} | |
bigint bigint::operator/(int m) | |
{ | |
if (m<0) | |
return -((*this)/(-m)); | |
if (m>100000) | |
return (*this)/bigint(m); | |
bigint c; | |
c.oper=oper; | |
c.length=length; | |
int t=0; | |
for (int i=c.length;i>=1;i--) | |
c.a[i]=(t=(t%m*10000+a[i]))/m; | |
c.check(); | |
return c; | |
} | |
bigint bigint::operator %(bigint m) | |
{ | |
return (*this)-((*this)/m)*m; | |
} | |
bigint bigint::operator%(int m) | |
{ | |
if (m<0) | |
return -((*this)%(-m)); | |
if (m>100000) | |
return (*this)%bigint(m); | |
int t=0; | |
for (int i=length;i>=1;i--) | |
t=(t*10000+a[i])%m; | |
return t; | |
} | |
bigint sqr(bigint m) | |
{ | |
return m*m; | |
} | |
bigint sqrt(bigint m) | |
{ | |
if (m.oper<0 || m.length==0) | |
return 0; | |
bigint c,last,now,templast; | |
c.length=(m.length+1)/2; | |
c.a[c.length]=int(sqrt((double)m.a[c.length*2]*10000+m.a[c.length*2-1])+1e-6); | |
templast.length=c.length*2; | |
templast.a[c.length*2-1]=(c.a[c.length]*c.a[c.length])%10000; | |
templast.a[c.length*2]=(c.a[c.length]*c.a[c.length])/10000; | |
templast.check(); | |
for (int i=c.length-1;i>=1;i--) | |
{ | |
last=templast; | |
int head=0,tail=10000,mid,j,temp; | |
while (head+1<tail) | |
{ | |
mid=(head+tail)/2; | |
now=last; | |
now.a[2*i-1]+=mid*mid; | |
for (j=i+1;j<=c.length;j++) | |
now.a[i+j-1]+=mid*c.a[j]*2; | |
now.length++; | |
for (j=2*i-1,temp=0;j<=now.length;j++) | |
now.a[j]=(temp=(temp/10000+now.a[j]))%10000; | |
now.check(); | |
if (now<=m) | |
{ | |
templast=now; | |
head=mid; | |
} | |
else | |
tail=mid; | |
} | |
c.a[i]=head; | |
} | |
c.check(); | |
return c; | |
} | |
bigint gcd(bigint a,bigint b) | |
{ | |
return (b==0)?a:gcd(b,a%b); | |
} | |
bigint lcm(bigint a,bigint b) | |
{ | |
return a*b/gcd(a,b); | |
} | |
void bigint::operator+=(bigint m) | |
{ | |
(*this)=(*this)+m; | |
} | |
void bigint::operator-=(bigint m) | |
{ | |
(*this)=(*this)-m; | |
} | |
void bigint::operator*=(bigint m) | |
{ | |
(*this)=(*this)*m; | |
} | |
void bigint::operator/=(bigint m) | |
{ | |
(*this)=(*this)/m; | |
} | |
void bigint::operator%=(bigint m) | |
{ | |
(*this)=(*this)%m; | |
} | |
void bigint::operator*=(int m) | |
{ | |
(*this)=(*this)*m; | |
} | |
void bigint::operator/=(int m) | |
{ | |
(*this)=(*this)/m; | |
} | |
void bigint::operator%=(int m) | |
{ | |
(*this)=(*this)%m; | |
} | |
char a[110], b[110]; | |
int main() | |
{ | |
bigint A,B,G; | |
while (cin>>a>>b) { | |
A = a; | |
B = b; | |
if (A==0 && B==0){ | |
return 0; | |
} | |
G = gcd(A, B); | |
writeln(A*B/G); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment