2017年09月10日21時17分13秒に更新されたバージョンを表示しています.
最新のページはこちらをご覧ください.
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)
#define ll long long
#define ull unsigned ll
void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void reader(ll *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void reader(double *x){scanf("%lf",x);}
int reader(char c[]){int i,s=0;for(;;){mygc(i);if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF) break;}c[s++]=i;for(;;){mygc(i);if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF) break;c[s++]=i;}c[s]='\0';return s;}
template <class T, class S> void reader(T *x, S *y){reader(x);reader(y);}
template <class T, class S, class U> void reader(T *x, S *y, U *z){reader(x);reader(y);reader(z);}
template <class T, class S, class U, class V> void reader(T *x, S *y, U *z, V *w){reader(x);reader(y);reader(z);reader(w);}
void writer(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
void writer(ll x, char c){int s=0,m=0;char f[20];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
void writer(double x, char c){printf("%.15f",x);mypc(c);}
void writer(const char c[]){int i;for(i=0;c[i]!='\0';i++)mypc(c[i]);}
void writer(const char x[], char c){int i;for(i=0;x[i]!='\0';i++)mypc(x[i]);mypc(c);}
template<class T> void writerLn(T x){writer(x,'\n');}
template<class T, class S> void writerLn(T x, S y){writer(x,' ');writer(y,'\n');}
template<class T, class S, class U> void writerLn(T x, S y, U z){writer(x,' ');writer(y,' ');writer(z,'\n');}
template<class T> void writerArr(T x[], int n){int i;if(!n){mypc('\n');return;}rep(i,n-1)writer(x[i],' ');writer(x[n-1],'\n');}
char memarr[17000000]; void *mem = memarr;
#define MD 1000000007
set<string> g_flags;
struct insertfunctions{
vector<string> name;
std::set<string> doit, already;
map<string,string> func, place;
map<string,vector<string> > need;
void set(){
{
string n = "stdc";
string c = "#include<bits/stdc++.h>\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "namespace";
string c = "using namespace std;\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "define_MD";
string c = "#define MD 1000000007\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "define_PI";
string c = "#define PI 3.14159265358979323846\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "workmemory";
string c = "inplace_L void *wmem; char memarr[64000000];";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory_init");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "workmemory_init";
string c = "wmem = memarr;";
string p = "main_first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "walloc1d";
string c = "template<class T> void walloc1d(T **arr, int x, void **mem = &wmem){ (*arr)=(T*)(*mem); (*mem)=((*arr)+x); }";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "walloc2d";
string c = "template<class T> void walloc2d(T ***arr, int x, int y, void **mem = &wmem){ int i; (*arr)=(T**)(*mem); (*arr)[0]=(T*)((*arr)+x); REP(i,1,x)(*arr)[i]=(*arr)[i-1]+y; (*mem)=((*arr)[x-1]+y); }";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "malloc1d";
string c = "template<class T>\nvoid malloc1d(T **arr, int x){\n (*arr) = (T*)malloc(x*sizeof(T));\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "free1d";
string c = "template<class T>\nvoid free1d(T *arr){\n free(arr);\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "malloc2d";
string c = "template<class T>\nvoid malloc2d(T ***arr, int x, int y){\n int i;\n (*arr) = (T**)malloc(x*sizeof(T*));\n (*arr)[0] = (T*)malloc(x*y*sizeof(T));\n REP(i,1,x)(*arr)[i]=(*arr)[i-1]+y;\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "free2d";
string c = "template<class T>\nvoid free2d(T **arr){\n free(arr[0]);\n free(arr);\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "sortA_2";
string c = "template<class T1, class T2>\nvoid sortA_L(int N, T1 a[], T2 b[], void *mem = wmem){\n int i;\n pair<T1, T2> *arr = (pair<T1, T2> *) mem;\n rep(i,N) arr[i].first = a[i], arr[i].second = b[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first, b[i] = arr[i].second;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "sortA_3";
string c = "template<class T1, class T2, class T3>\nvoid sortA_L(int N, T1 a[], T2 b[], T3 c[], void *mem = wmem){\n int i;\n pair<T1, pair<T2, T3> > *arr = (pair<T1, pair<T2, T3> > *) mem;\n rep(i,N) arr[i].first = a[i], arr[i].second.first = b[i], arr[i].second.second = c[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first, b[i] = arr[i].second.first, c[i] = arr[i].second.second;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "sortA_4";
string c = "template<class T1, class T2, class T3, class T4>\nvoid sortA_L(int N, T1 a[], T2 b[], T3 c[], T4 d[], void *mem = wmem){\n int i;\n pair<pair<T1, T2>, pair<T3, T4> > *arr = (pair<pair<T1, T2>, pair<T3, T4> > *) mem;\n rep(i,N) arr[i].first.first = a[i], arr[i].first.second = b[i], arr[i].second.first = c[i], arr[i].second.second = d[i];\n sort(arr, arr+N);\n rep(i,N) a[i] = arr[i].first.first, b[i] = arr[i].first.second, c[i] = arr[i].second.first, d[i] = arr[i].second.second;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "mint";
string c = "struct mint{\n static unsigned md, W, R, Rinv, mdninv, RR;\n unsigned val;\n\n mint(){}\n mint(int a){val = mulR(a);}\n mint(unsigned a){val = mulR(a);}\n mint(ll a){val = mulR(a);}\n mint(ull a){val = mulR(a);}\n\n int get_inv(ll a, int md){ll t=a,s=md,u=1,v=0,e;while(s){e=t/s;t-=e*s;u-=e*v;swap(t,s);swap(u,v);}if(u<0)u+=md;return u;}\n\n void setmod(unsigned m){\n int i;\n unsigned t;\n W = 32;\n md = m;\n R = (1ULL << W) % md;\n RR = (ull)R*R % md;\n switch(m){\n case 104857601:\n Rinv = 2560000;\n mdninv = 104857599;\n break;\n case 998244353:\n Rinv = 232013824;\n mdninv = 998244351;\n break;\n case 1000000007:\n Rinv = 518424770;\n mdninv = 2226617417U;\n break;\n case 1000000009:\n Rinv = 171601999;\n mdninv = 737024967;\n break;\n case 1004535809:\n Rinv = 234947584;\n mdninv = 1004535807;\n break;\n case 1007681537:\n Rinv = 236421376;\n mdninv = 1007681535;\n break;\n case 1012924417:\n Rinv = 238887936;\n mdninv = 1012924415;\n break;\n case 1045430273:\n Rinv = 254466304;\n mdninv = 1045430271;\n break;\n case 1051721729:\n Rinv = 257538304;\n mdninv = 1051721727;\n break;\n default:\n Rinv = get_inv(R, md);\n mdninv = 0;\n t = 0;\n rep(i,(int)W){\n if(t%2==0) t+=md, mdninv |= (1U<<i);\n t /= 2;\n }\n }\n }\n\n unsigned mulR(unsigned a){\n return (ull)a*R%md;\n }\n\n unsigned mulR(int a){\n if(a < 0) a = a%md+md;\n return mulR((unsigned)a);\n }\n\n unsigned mulR(ull a){\n return mulR((unsigned)(a%md));\n }\n\n unsigned mulR(ll a){\n a %= md;\n if(a < 0) a += md;\n return mulR((unsigned)a);\n }\n\n unsigned reduce(unsigned T){\n unsigned m = T * mdninv;\n unsigned t = (unsigned)((T + (ull)m*md) >> W);\n if(t >= md) t -= md;\n return t;\n }\n\n unsigned reduce(ull T){\n unsigned m = (unsigned)T * mdninv;\n unsigned t = (unsigned)((T + (ull)m*md) >> W);\n if(t >= md) t -= md;\n return t;\n }\n\n unsigned get(){\n return reduce(val);\n }\n\n mint &operator+=(mint a){\n val += a.val;\n if(val >= md) val -= md;\n return *this;\n }\n mint &operator-=(mint a){\n if(val < a.val) val = val + md - a.val;\n else val -= a.val;\n return *this;\n }\n mint &operator*=(mint a){\n val = reduce((ull)val*a.val);\n return *this;\n }\n mint &operator/=(mint a){\n return *this *= a.inverse();\n }\n\n mint operator+(mint a){ return mint(*this)+=a; }\n mint operator-(mint a){ return mint(*this)-=a; }\n mint operator*(mint a){ return mint(*this)*=a; }\n mint operator/(mint a){ return mint(*this)/=a; }\n\n mint operator+(int a){ return mint(*this)+=mint(a); }\n mint operator-(int a){ return mint(*this)-=mint(a); }\n mint operator*(int a){ return mint(*this)*=mint(a); }\n mint operator/(int a){ return mint(*this)/=mint(a); }\n mint operator+(ll a){ return mint(*this)+=mint(a); }\n mint operator-(ll a){ return mint(*this)-=mint(a); }\n mint operator*(ll a){ return mint(*this)*=mint(a); }\n mint operator/(ll a){ return mint(*this)/=mint(a); }\n\n mint operator-(void){ mint res; if(val) res.val=md-val; else res.val=0; return res; }\n \n operator bool(void){\n return val!=0;\n }\n operator int(void){\n return get();\n }\n operator ll(void){\n return get();\n }\n\n mint inverse(){\n int a = val, b = md, u = 1, v = 0, t;\n mint res;\n while(b){\n t = a / b;\n a -= t * b; swap(a, b);\n u -= t * v; swap(u, v);\n }\n if(u < 0) u += md;\n res.val = (ull)u*RR % md;\n return res;\n }\n\n mint pw(ull b){\n mint a(*this), res;\n res.val = R;\n while(b){\n if(b&1) res *= a;\n b >>= 1;\n a *= a;\n }\n return res;\n }\n\n bool operator==(int a){return mulR(a)==val;}\n bool operator!=(int a){return mulR(a)!=val;}\n};\nunsigned mint::md, mint::W, mint::R, mint::Rinv, mint::mdninv, mint::RR;\nmint operator+(int a, mint b){return mint(a)+=b;}\nmint operator-(int a, mint b){return mint(a)-=b;}\nmint operator*(int a, mint b){return mint(a)*=b;}\nmint operator/(int a, mint b){return mint(a)/=b;}\nmint operator+(ll a, mint b){return mint(a)+=b;}\nmint operator-(ll a, mint b){return mint(a)-=b;}\nmint operator*(ll a, mint b){return mint(a)*=b;}\nmint operator/(ll a, mint b){return mint(a)/=b;}\n";
string p = "first";
vector<string> d;
d.push_back((string)"mint_init");
d.push_back((string)"define_MD");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "mint_init";
string c = "{mint x; x.setmod(MD);}";
string p = "main_first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reader_int";
string c = "void rd(int &x){\n int k, m=0;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if(k=='-'){\n m=1;\n break;\n }\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n if(m){\n x=-x;\n }\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reader_ll";
string c = "void rd(ll &x){\n int k, m=0;\n x=0;\n for(;;){\n k = getchar_unlocked();\n if(k=='-'){\n m=1;\n break;\n }\n if('0'<=k&&k<='9'){\n x=k-'0';\n break;\n }\n }\n for(;;){\n k = getchar_unlocked();\n if(k<'0'||k>'9'){\n break;\n }\n x=x*10+k-'0';\n }\n if(m){\n x=-x;\n }\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reader_mint";
string c = "void rd(mint &x){int i; rd(i); x=i;}\n";
string p = "first";
vector<string> d;
d.push_back((string)"reader_int");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reader_double";
string c = "void rd(double &x){scanf(\"%lf\",&x);}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reader_char_array";
string c = "int rd(char c[]){\n int i, sz = 0;\n for(;;){\n i = getchar_unlocked();\n if(i!=' '&&i!='\\n'&&i!='\\r'&&i!='\\t'&&i!=EOF) break;\n }\n c[sz++] = i;\n for(;;){\n i = getchar_unlocked();\n if(i==' '||i=='\\n'||i=='\\r'||i=='\\t'||i==EOF) break;\n c[sz++] = i;\n }\n c[sz]='\\0';\n return sz;\n}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_int";
string c = "void wt_L(int x){\n int s=0, m=0;\n char f[10];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(f[s]+'0');\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_int_withBase";
string c = "void wt_L(int x, int b){\n int s=0, m=0;\n char f[35];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%b, x/=b;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"[f[s]]);\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_ll";
string c = "void wt_L(ll x){\n int s=0, m=0;\n char f[20];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%10, x/=10;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(f[s]+'0');\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_ll_withBase";
string c = "void wt_L(ll x, int b){\n int s=0, m=0;\n char f[70];\n if(x<0) m=1, x=-x;\n while(x) f[s++]=x%b, x/=b;\n if(!s) f[s++]=0;\n if(m) putchar_unlocked('-');\n while(s--) putchar_unlocked(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"[f[s]]);\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_mint";
string c = "void wt_L(mint x){int i; i = (int)x; wt_L(i);}";
string p = "first";
vector<string> d;
d.push_back((string)"writer_int");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_double";
string c = "void wt_L(double x){printf(\"%.15f\",x);}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "writer_char_array";
string c = "void wt_L(const char c[]){\n int i=0;\n for(i=0;c[i]!='\\0';i++) putchar_unlocked(c[i]);\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "pow2";
string c = "template<class T> inline T pow2_L(T a){ return a*a; }";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "pow3";
string c = "template<class T> inline T pow3_L(T a){ return a*a*a; }";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "pow4";
string c = "template<class T> inline T pow4_L(T a){ return a*a*a*a; }";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "pow";
string c = "template<class T> inline T pow_L(T a, int b){int i; T res = 1; rep(i,b) res *= a; return res; }";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "min_L";
string c = "template<class S, class T> inline S min_L(S a,T b){return a<=b?a:b;}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "max_L";
string c = "template<class S, class T> inline S max_L(S a,T b){return a>=b?a:b;}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "gcd";
string c = "template<class T> inline T GCD_L(T a,T b){T r; while(a)r=b,b=a,a=r%a; return b;}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "lcm";
string c = "template<class T> inline T LCM_L(T a,T b){return a/GCD_L(a,b)*b;}";
string p = "first";
vector<string> d;
d.push_back((string)"gcd");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "combination_mint";
string c = "struct combination_mint{\n mint *fac, *ifac;\n\n void init(int n, void **mem = &wmem){\n int i;\n \n walloc1d(&fac, n, mem);\n walloc1d(&ifac, n, mem);\n \n fac[0] = 1;\n rep(i,1,n) fac[i] = fac[i-1] * i;\n ifac[n-1] = 1 / fac[n-1];\n for(i=n-2;i>=0;i--) ifac[i] = ifac[i+1] * (i+1);\n }\n\n mint C(int a, int b){\n if(b < 0 || b > a) return 0;\n return fac[a]*ifac[b]*ifac[a-b];\n }\n\n mint P(int a, int b){\n if(b < 0 || b > a) return 0;\n return fac[a]*ifac[a-b];\n }\n\n mint H(int a, int b){\n if(a==0 && b==0) return 1;\n if(a<=0 || b<0) return 0;\n return C(a+b-1, b);\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"mint");
d.push_back((string)"workmemory");
d.push_back((string)"walloc1d");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "reduceFraction";
string c = "template<class T> void reduceFraction(T&a, T&b){T g=GCD_L(a,b);a/=g;b/=g;}";
string p = "first";
vector<string> d;
d.push_back((string)"gcd");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "runLength";
string c = "template<class T>\nint runLength(int N, T *arr, T *val, int *len){\n int i, rN;\n if(N==0) return 0;\n rN = 1;\n val[0] = arr[0];\n len[0] = 1;\n rep(i,1,N){\n if(val[rN-1] == arr[i]){\n len[rN-1]++;\n } else {\n val[rN] = arr[i];\n len[rN] = 1;\n rN++;\n }\n }\n return rN;\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "divup";
string c = "template<class S, class T> inline S divup_L(S a, T b){ return (a+b-1)/b; }";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "chmin";
string c = "template<class S, class T> inline S chmin(S &a, T b){if(a>b)a=b;return a;}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "chmax";
string c = "template<class S, class T> inline S chmax(S &a, T b){if(a<b)a=b;return a;}";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "fibonacci_mod";
string c = "int fibonacci_mod_L(ull n, int md){\n ull a=1, b=0, c=1, ma=1, mb=1, mc=0, ta, tb, tc;\n while(n){\n if(n%2){\n ta = a*ma + b*mb;\n tb = a*mb + b*mc;\n tc = b*mb + c*mc;\n a = ta % md;\n b = tb % md;\n c = tc % md;\n }\n ta = ma*ma + mb*mb;\n tb = ma*mb + mb*mc;\n tc = mb*mb + mc*mc;\n ma = ta % md;\n mb = tb % md;\n mc = tc % md;\n n/=2;\n }\n return b;\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "Unique1";
string c = "template<class T>\nvoid Unique_L(int &N, T A[], int sorted=0){\n int i, k;\n if(!sorted) sort(A, A+N);\n k = 0;\n rep(i,N) if(k==0 || A[k-1]!=A[i]) A[k++] = A[i];\n N = k;\n}\n";
string p = "first";
vector<string> d;
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "Unique2";
string c = "template<class T, class S>\nvoid Unique_L(int &N, T A[], S B[], int sorted=0){\n int i, k = 0;\n if(!sorted) sortA(N, A, B);\n rep(i,N){\n if(!k || A[k-1]!=A[i]){\n A[k] = A[i];\n B[k] = B[i];\n k++;\n } else {\n B[k-1] += B[i];\n }\n }\n N=k;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"sortA_2");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "coordcomp_1";
string c = "template<class T>\nint coordcomp_L(int n, T arr[], int res[] = NULL, void *mem = wmem){\n int i, k = 0;\n pair<T,int> *r = (pair<T,int>*)mem;\n\n rep(i,n) r[i].first = arr[i], r[i].second = i;\n sort(r, r+n);\n\n if(res != NULL){\n rep(i,n){\n if(i && r[i].first != r[i-1].first) k++;\n res[r[i].second] = k;\n }\n } else {\n rep(i,n){\n if(i && r[i].first != r[i-1].first) k++;\n arr[r[i].second] = k;\n }\n }\n return k+1;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "coordcomp_2";
string c = "template<class T>\nint coordcomp_L(int n1, T arr1[], int n2, T arr2[], int res1[] = NULL, int res2[] = NULL, void *mem = wmem){\n int i, k = 0;\n pair<T,int> *r = (pair<T,int>*)mem;\n\n rep(i,n1) r[i].first = arr1[i], r[i].second = i;\n rep(i,n2) r[n1+i].first = arr2[i], r[n1+i].second = n1+i;\n sort(r, r+n1+n2);\n\n rep(i,n1+n2){\n if(i && r[i].first != r[i-1].first) k++;\n if(r[i].second < n1){\n if(res1!=NULL) res1[r[i].second] = k;\n else arr1[r[i].second] = k;\n } else {\n if(res2!=NULL) res2[r[i].second-n1] = k;\n else arr2[r[i].second-n1] = k;\n }\n }\n\n return k+1;\n}\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "segtree";
string c = "template<class T>\nstruct segtree{\n int N, logN;\n T *sum, *mn;\n int *mnind;\n\n T *fixval; char *fixed;\n T *addval;\n\n void malloc(int maxN, int once = 0){\n int i;\n for(i=1;i<maxN;i*=2);\n \n sum = (T*)std::malloc(sizeof(T)*2*i);\n mn = (T*)std::malloc(sizeof(T)*2*i);\n mnind = (int*)std::malloc(sizeof(T)*2*i);\n fixval = (T*)std::malloc(sizeof(T)*i);\n addval = (T*)std::malloc(sizeof(T)*i);\n fixed = (char*)std::malloc(sizeof(char)*i);\n\n if(once) setN(maxN);\n }\n\n void walloc(int maxN, int once = 0, void **mem = &wmem){\n int i;\n for(i=1;i<maxN;i*=2);\n \n sum = (T*)(*mem);\n mn = sum + 2*i;\n mnind = (int*)(mn + 2*i);\n fixval = (T*)(mnind + 2*i);\n addval = fixval + i;\n fixed = (char*)(addval + i);\n *mem = fixed + i;\n\n if(once) setN(maxN);\n }\n\n void free(void){\n std::free(sum);\n std::free(mn);\n std::free(mnind);\n std::free(fixval);\n std::free(addval);\n std::free(fixed);\n }\n\n T& operator[](int i){\n return sum[N+i];\n }\n \n void setN(int n, int zerofill = 1, int dobuild = 1){\n int i;\n for(i=1,logN=0;i<n;i*=2,logN++);\n N = i;\n if(zerofill) rep(i,N) sum[N+i] = 0;\n if(dobuild) build();\n }\n \n void build(void){\n int i;\n rep(i,N) mn[N+i] = sum[N+i], mnind[N+i] = i;\n for(i=N-1;i;i--){\n sum[i] = sum[2*i] + sum[2*i+1];\n if(mn[2*i] <= mn[2*i+1]){\n mn[i] = mn[2*i];\n mnind[i] = mnind[2*i];\n } else {\n mn[i] = mn[2*i+1];\n mnind[i] = mnind[2*i+1];\n }\n }\n REP(i,1,N) fixed[i] = 0;\n REP(i,1,N) addval[i] = 0;\n }\n \n inline void push_one(int a, int sz, int st){\n if(fixed[a]){\n if(sz > 1){\n fixed[a*2] = fixed[a*2+1] = 1;\n fixval[a*2] = fixval[a*2+1] = fixval[a];\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n mn[a*2] = mn[a*2+1] = fixval[a];\n mnind[a*2] = st;\n mnind[a*2+1] = st + sz;\n } else {\n sum[a*2] = sum[a*2+1] = sz * fixval[a];\n mn[a*2] = mn[a*2+1] = fixval[a];\n mnind[a*2] = st;\n mnind[a*2+1] = st + sz;\n }\n fixed[a] = 0;\n addval[a] = 0;\n return;\n }\n if(addval[a] != 0){\n if(sz > 1){\n if(fixed[a*2]) fixval[a*2] += addval[a];\n else addval[a*2] += addval[a];\n if(fixed[a*2+1]) fixval[a*2+1] += addval[a];\n else addval[a*2+1] += addval[a];\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n mn[a*2] += addval[a];\n mn[a*2+1] += addval[a];\n } else {\n sum[a*2] += sz * addval[a];\n sum[a*2+1] += sz * addval[a];\n mn[a*2] += addval[a];\n mn[a*2+1] += addval[a];\n }\n addval[a] = 0;\n return;\n }\n }\n \n inline void push(int a){\n int i, aa = a - N, nd, sz, st;\n for(i=logN;i;i--){\n nd = a>>i;\n sz = 1<<(i-1);\n st = 2 * sz * (aa>>i);\n push_one(nd, sz, st);\n }\n }\n \n inline void build(int a){\n int sz = 1, st = a - N;\n while(a > 1){\n if(a%2) st += sz;\n a /= 2;\n sz *= 2;\n if(fixed[a]){\n sum[a] = sz * fixval[a];\n mn[a] = fixval[a];\n } else {\n sum[a] = sum[a*2] + sum[a*2+1];\n if(mn[a*2] <= mn[a*2+1]){\n mn[a] = mn[a*2];\n mnind[a] = mnind[a*2];\n } else {\n mn[a] = mn[a*2+1];\n mnind[a] = mnind[a*2+1];\n }\n if(addval[a] != 0){\n mn[a] += addval[a];\n sum[a] += sz * addval[a];\n }\n }\n }\n }\n \n inline void change(int a, int b, T val){\n int sz = 1, aa, bb, st_a = a, st_b = b;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] = mn[a] = val;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n sum[b] = mn[b] = val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n fixed[a]=1, fixval[a]=val;\n sum[a] = sz * val;\n mn[a] = val;\n mnind[a] = st_a;\n a++;\n st_a += sz;\n }\n if(b%2){\n b--;\n st_b -= sz;\n fixed[b]=1, fixval[b]=val;\n sum[b] = sz * val;\n mn[b] = val;\n mnind[b] = st_b;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline void add(int a, int b, T val){\n int sz = 1, aa, bb;\n if(a >= b) return;\n \n aa = (a += N);\n bb = (b += N);\n push(a); push(b-1);\n \n if(a%2){\n sum[a] += val;\n mn[a] += val;\n a++;\n }\n if(b%2){\n b--;\n sum[b] += val;\n mn[b] += val;\n }\n a /= 2;\n b /= 2;\n \n while(a < b){\n sz *= 2;\n if(a%2){\n if(fixed[a]) fixval[a] += val; else addval[a] += val;\n sum[a] += sz * val;\n mn[a] += val;\n a++;\n }\n if(b%2){\n b--;\n if(fixed[b]) fixval[b] += val; else addval[b] += val;\n sum[b] += sz * val;\n mn[b] += val;\n }\n a /= 2;\n b /= 2;\n }\n \n build(aa);\n build(bb-1);\n }\n \n inline pair<T,int> getMin(int a, int b){\n pair<T,int> res;\n int sz = 1;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n res.first = numeric_limits<T>::max();\n res.second = -1;\n while(a < b){\n if(a%2){\n res <?= make_pair(mn[a], mnind[a]);\n a++;\n }\n if(b%2){\n b--;\n res <?= make_pair(mn[b], mnind[b]);\n }\n a /= 2;\n b /= 2;\n }\n return res;\n }\n\n inline T getMinVal(int a, int b){\n return getMin(a,b).first;\n }\n \n inline int getMinInd(int a, int b){\n return getMin(a,b).second;\n }\n\n inline T getSum(int a, int b){\n T res;\n int sz = 1;\n \n a += N;\n b += N;\n push(a); push(b-1);\n \n res = 0;\n while(a < b){\n if(a%2) res += sum[a++];\n if(b%2) res += sum[--b];\n a /= 2;\n b /= 2;\n }\n return res;\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"chmin");
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "graph";
string c = "struct graph{\n int N, *es, **edge;\n\n void setEdge(int N__, int M, int A[], int B[], void **mem = &wmem){\n int i;\n N = N__;\n es = (int*)(*mem);\n edge = (int**)(es+N);\n edge[0] = (int*)(edge+N);\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++, es[B[i]]++;\n rep(i,1,N) edge[i] = edge[i-1] + es[i-1];\n (*mem) = edge[N-1] + es[N-1];\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i], edge[B[i]][es[B[i]]++] = A[i];\n }\n\n void setDirectEdge(int N__, int M, int A[], int B[], void **mem = &wmem){\n int i;\n N = N__;\n es = (int*)(*mem);\n edge = (int**)(es+N);\n edge[0] = (int*)(edge+N);\n rep(i,N) es[i] = 0;\n rep(i,M) es[A[i]]++;\n rep(i,1,N) edge[i] = edge[i-1] + es[i-1];\n (*mem) = edge[N-1] + es[N-1];\n rep(i,N) es[i] = 0;\n rep(i,M) edge[A[i]][es[A[i]]++] = B[i];\n }\n\n graph reverse(void **mem = &wmem){\n int i, j, k;\n graph g;\n\n g.N = N;\n g.es = (int*)(*mem);\n g.edge = (int**)(g.es + N);\n g.edge[0] = (int*)(g.edge + N);\n\n rep(i,N) g.es[i] = 0;\n rep(i,N) rep(j,es[i]) g.es[edge[i][j]]++;\n\n rep(i,1,N) g.edge[i] = g.edge[i-1] + g.es[i-1];\n *mem = g.edge[N-1] + g.es[N-1];\n\n rep(i,N) g.es[i] = 0;\n rep(i,N) rep(j,es[i]){\n k = edge[i][j];\n g.edge[k][g.es[k]++] = i;\n }\n\n return g;\n }\n\n graph reduce(int tn, int ind[], int self_e = 0, int dep_e = 0, void **mem = &wmem){\n int i, j, k, M = 0;\n int x, y;\n graph g;\n pair<int,int> *A;\n\n rep(i,N) M += es[i];\n A = (pair<int,int>*)((int*)((int**)(*mem) + tn) + tn + M);\n\n M = 0;\n rep(i,N){\n x = ind[i];\n if(x < 0) continue;\n rep(j,es[i]){\n y = ind[edge[i][j]];\n if(y < 0) continue;\n if(self_e==0 && x==y) continue;\n A[M++] = make_pair(x, y);\n }\n }\n\n if(dep_e==0){\n sort(A, A+M);\n k = 0;\n rep(i,M){\n if(k && A[k-1]==A[i]) continue;\n A[k++] = A[i];\n }\n M = k;\n }\n\n g.N = tn;\n g.es = (int*)(*mem);\n g.edge = (int**)(g.es + tn);\n g.edge[0] = (int*)(g.edge + tn);\n\n rep(i,tn) g.es[i] = 0;\n rep(i,M) g.es[A[i].first]++;\n\n rep(i,1,tn) g.edge[i] = g.edge[i-1] + g.es[i-1];\n *mem = g.edge[tn-1] + g.es[tn-1];\n\n rep(i,tn) g.es[i] = 0;\n rep(i,M){\n j = A[i].first;\n k = A[i].second;\n g.edge[j][g.es[j]++] = k;\n }\n return g;\n }\n\n void getDist(int root, int res[], void *mem = wmem){\n int i,j,k,*q,s,z;\n q=(int*)mem;\n rep(i,N)res[i]=-1;\n res[root]=0;\n s=0;\n z=1;\n q[0]=root;\n while(z){\n i=q[s++];\n z--;\n rep(j,es[i]){\n k=edge[i][j];\n if(res[k]>=0)continue;\n res[k]=res[i]+1;\n q[s+z++]=k;\n }\n }\n }\n\n\n inline int sccDFS(int num[], int st, int mx){\n int i,j;\n num[st]=-2;\n rep(i,es[st]) {\n j=edge[st][i]; if(num[j]==-1) mx=sccDFS(num,j,mx);\n }\n num[st]=mx; return mx+1;\n }\n \n int scc(int res[], void *mem = wmem){\n int i, j, k, ret=0;\n graph r;\n int *st, st_size, *num, *nrv;\n \n r = reverse(&mem);\n st = (int*)mem; num = st+N; nrv = num + N;\n \n rep(i,N) res[i] = num[i] = -1;\n k = 0;\n rep(i,N) if(num[i]==-1) k = sccDFS(num,i,k);\n rep(i,N) nrv[num[i]] = i;\n \n for(k=N-1;k>=0;k--) {\n i=nrv[k]; if(res[i]>=0)continue;\n res[i]=ret; st_size=0; st[st_size++]=i;\n while(st_size){\n i=st[--st_size];\n rep(j,r.es[i])\n if(res[r.edge[i][j]]==-1) res[r.edge[i][j]]=ret, st[st_size++]=r.edge[i][j];\n }\n ret++;\n }\n \n return ret;\n }\n\n\n\n inline void bccDFS(int v, int u, int *res, int *rt, int &rts, int *S, int &Ss, int *inS, int *num, int &tm){\n int i, k;\n \n num[v] = ++tm;\n S[Ss++] = v; inS[v] = 1;\n rt[rts++] = v;\n rep(i, es[v]){\n int w = edge[v][i];\n if(!num[w]){\n bccDFS(w, v, res, rt, rts, S, Ss, inS, num, tm);\n } else if(u != w && inS[w]){\n while(num[rt[rts-1]] > num[w]) rts--;\n }\n }\n \n if(v == rt[rts-1]){\n k = S[Ss-1];\n for(;;){\n int w = S[--Ss];\n inS[w] = 0;\n res[w] = k;\n if(v==w) break;\n }\n rts--;\n }\n }\n\n int bcc(int res[], void *mem=wmem){\n int i, k;\n int *rt, *S, *num, *inS;\n pair<int,int> *arr;\n int rts = 0, Ss = 0, tm = 0;\n \n num = (int*)mem;\n rt = num + N;\n S = rt + N;\n inS = S + N;\n \n memset(num, 0, sizeof(int)*N);\n memset(inS, 0, sizeof(int)*N);\n rep(i,N) if(!num[i]) bccDFS(i, N, res, rt, rts, S, Ss, inS, num, tm);\n \n arr = (pair<int,int>*)mem;\n rep(i,N) arr[i].first = res[i], arr[i].second = i;\n sort(arr, arr+N);\n k = 0;\n rep(i,N){\n if(i && arr[i].first != arr[i-1].first) k++;\n res[arr[i].second] = k;\n }\n return k+1;\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "HLD";
string c = "struct HLD{\n int N;\n int *es, **edge;\n\n int *group, *groupind;\n int groupNum, *groupSize, **groupNode, *groupUpNode, *groupDepth;\n\n void init(graph g, void **mem = &wmem){\n init(g.N, g.es, g.edge, mem);\n }\n \n void init(int N__, int *es__, int **edge__, void **mem = &wmem){\n int i, j, k, x, y, mx;\n int *q, q_st, q_ed, *sz;\n char *vis;\n\n N = N__;\n es = es__;\n edge = edge__;\n\n group = (int*)(*mem);\n groupind = group + N;\n *mem = groupind + N;\n \n q = (int*)(*mem);\n sz = q + N;\n vis = (char*)(sz + N);\n rep(i,N) vis[i] = 0;\n q_st = 0; q_ed = 1;\n q[0] = 0; vis[0] = 1;\n while(q_st < q_ed){\n i = q[q_st++];\n rep(j,es[i]){\n k = edge[i][j];\n if(!vis[k]) vis[k] = 1, q[q_ed++] = k;\n }\n }\n \n rep(i,N) sz[i] = 0;\n for(j=N-1;j>=0;j--){\n i = q[j];\n sz[i] = 1;\n rep(k,es[i]) sz[i] += sz[edge[i][k]];\n }\n\n rep(i,N) group[i] = -1;\n\n groupNum = 0;\n rep(j,N){\n i = q[j];\n if(group[i]>=0) continue;\n\n group[i] = groupNum++;\n groupind[i] = 0;\n for(;;){\n mx = -1;\n rep(k,es[i]){\n if(group[edge[i][k]] != -1) continue;\n if(mx==-1) mx = k;\n else if(sz[edge[i][k]] > sz[edge[i][mx]]) mx = k;\n }\n if(mx==-1) break;\n group[edge[i][mx]] = group[i];\n groupind[edge[i][mx]] = groupind[i]+1;\n i = edge[i][mx];\n }\n }\n\n groupSize = (int*)(*mem);\n groupUpNode = groupSize + groupNum;\n groupDepth = groupUpNode + groupNum;\n\n rep(i,groupNum) groupSize[i] = 0;\n rep(i,N) groupSize[group[i]]++;\n groupNode = (int**)(groupDepth + groupNum);\n groupNode[0] = (int*)(groupNode + groupNum);\n REP(i,1,groupNum) groupNode[i] = groupNode[i-1] + groupSize[i-1];\n *mem = groupNode[groupNum-1] + groupSize[groupNum-1];\n\n rep(i,N) groupNode[group[i]][groupind[i]] = i;\n\n rep(i,groupNum) groupDepth[i] = -1;\n groupUpNode[0] = -1;\n groupDepth[0] = 0;\n rep(x,groupNum) rep(y,groupSize[x]){\n i = groupNode[x][y];\n rep(j,es[i]){\n k = edge[i][j];\n if(x != group[k] && groupDepth[group[k]]==-1){\n groupUpNode[group[k]] = i;\n groupDepth[group[k]] = groupDepth[x] + 1;\n }\n }\n }\n }\n \n int lca(int x, int y){\n int x1, y1, x2, y2;\n x1 = group[x]; x2 = groupind[x];\n y1 = group[y]; y2 = groupind[y];\n while(groupDepth[x1] > groupDepth[y1]){\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n }\n while(groupDepth[x1] < groupDepth[y1]){\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n while(x1 != y1){\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n \n if(x2 <= y2) return x;\n return y;\n }\n\n int depth(int x){\n int x1, x2, res = 0;\n x1 = group[x];\n x2 = groupind[x];\n while(groupUpNode[x1] != -1){\n res += x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x];\n x2 = groupind[x];\n }\n return res + x2;\n }\n\n int dist(int x, int y){\n int x1, y1, x2, y2, res = 0;\n x1 = group[x]; x2 = groupind[x];\n y1 = group[y]; y2 = groupind[y];\n while(groupDepth[x1] > groupDepth[y1]){\n res += x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n }\n while(groupDepth[x1] < groupDepth[y1]){\n res += y2 + 1;\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n while(x1 != y1){\n res += x2 + y2 + 2;\n x = groupUpNode[x1];\n x1 = group[x]; x2 = groupind[x];\n y = groupUpNode[y1];\n y1 = group[y]; y2 = groupind[y];\n }\n\n if(x2 <= y2) return res + y2 - x2;\n return res + x2 - y2;\n }\n\n int up(int x){\n int x1 = group[x];\n int x2 = groupind[x];\n if(x2==0) return groupUpNode[x1];\n return groupNode[x1][x2-1];\n }\n\n int up(int x, int d){\n int x1 = group[x];\n int x2 = groupind[x];\n while(d > x2){\n if(groupUpNode[x1]==-1) return -1;\n d -= x2 + 1;\n x = groupUpNode[x1];\n x1 = group[x];\n x2 = groupind[x];\n }\n return groupNode[x1][x2-d];\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
d.push_back((string)"graph");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "HLD_segtree";
string c = "template<class T>\nstruct HLD_segtree{\n HLD *hld;\n segtree<T> *seg;\n\n void init(HLD *hld__, T initval[], void **mem = &wmem){\n int i, j;\n\n hld = hld__;\n seg = (segtree<T>*)(*mem);\n *mem = seg + hld->groupNum;\n\n rep(i,hld->groupNum){\n seg[i].walloc(hld->groupSize[i], 0, mem);\n seg[i].setN(hld->groupSize[i], 0, 0);\n if(initval!=NULL) rep(j,hld->groupSize[i]) seg[i][j] = initval[ hld->groupNode[i][j] ];\n else rep(j,hld->groupSize[i]) seg[i][j] = 0;\n seg[i].build();\n }\n }\n\n inline void change(int u, int v, T val){\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n seg[ug].change(0, hld->groupind[u]+1, val);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n seg[ug].change(min(ui,vi), max(ui,vi)+1, val);\n }\n\n inline void add(int u, int v, T val){\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n seg[ug].add(0, hld->groupind[u]+1, val);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n seg[ug].add(min(ui,vi), max(ui,vi)+1, val);\n }\n\n inline pair<T,int> getMin(int u, int v){\n pair<T,int> res, tmp;\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n\n res.first = numeric_limits<T>::max();\n res.second = -1;\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n tmp = seg[ug].getMin(0, hld->groupind[u]+1);\n tmp.second = hld->groupNode[ug][tmp.second];\n res <?= tmp;\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n tmp = seg[ug].getMin(min(ui,vi), max(ui,vi)+1);\n tmp.second = hld->groupNode[ug][tmp.second];\n res <?= tmp;\n return res;\n }\n\n inline T getMinVal(int u, int v){\n return getMin(u,v).first;\n }\n\n inline int getMinInd(int u, int v){\n return getMin(u,v).second;\n }\n\n inline T getSum(int u, int v){\n T res;\n int ug, vg, ui, vi;\n ug = hld->group[u];\n vg = hld->group[v];\n\n res = 0;\n while(ug != vg){\n if(hld->groupDepth[ug] < hld->groupDepth[vg]){\n swap(u, v);\n swap(ug, vg);\n }\n res += seg[ug].getSum(0, hld->groupind[u]+1);\n u = hld->groupUpNode[ug];\n ug = hld->group[u];\n }\n ui = hld->groupind[u];\n vi = hld->groupind[v];\n res += seg[ug].getSum(min(ui,vi), max(ui,vi)+1);\n return res;\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"workmemory");
d.push_back((string)"graph");
d.push_back((string)"HLD");
d.push_back((string)"min_L");
d.push_back((string)"max_L");
d.push_back((string)"segtree");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
{
string n = "maxflow";
string c = "template<class T, class S>\nstruct maxflow{\n int node, st, ed;\n int *es, *emem, **edge, **rev, *level, *queue;\n T **flow, eps;\n\n void malloc(int N){\n int i;\n es = (int*)std::malloc(N*sizeof(int));\n emem = (int*)std::malloc(N*sizeof(int));\n level = (int*)std::malloc(N*sizeof(int));\n queue = (int*)std::malloc(N*sizeof(int));\n edge = (int**)std::malloc(N*sizeof(int*));\n rev = (int**)std::malloc(N*sizeof(int*));\n flow = (T**)std::malloc(N*sizeof(T*));\n rep(i,N) emem[i] = 0, edge[i] = rev[i] = NULL, flow[i] = NULL;\n }\n\n void walloc(int N, void**mem = &wmem){\n int i;\n es = (int*)(*mem);\n emem = es + N;\n level = emem + N;\n queue = level + N;\n edge = (int**)(queue + N);\n rev = edge + N;\n flow = (T**)(rev + N);\n rep(i,N) emem[i] = 0, edge[i] = rev[i] = NULL, flow[i] = NULL;\n (*mem) = (flow + N);\n }\n\n void levelize(void){\n int i, j, k, t;\n int q_st = 0, q_ed = 1;\n rep(i,node) level[i] = -1;\n level[st] = 0;\n queue[0] = st;\n while(q_st != q_ed){\n i = queue[q_st++];\n t = level[i] + 1;\n rep(j,es[i]) if(flow[i][j] > eps){\n k = edge[i][j];\n if(level[k]!=-1) continue;\n level[k] = t;\n queue[q_ed++] = k;\n if(k==ed) return;\n }\n }\n }\n\n S pushflow(int i, S lim){\n int j, k, ji;\n S s, t, res = 0;\n if(i==ed) return lim;\n rep(j,es[i]) if(flow[i][j] > eps){\n k = edge[i][j];\n if(level[k] != level[i]+1) continue;\n s = min(lim, (S)flow[i][j]);\n t = pushflow(k, s); if(!t) continue;\n res += t;\n lim -= t;\n ji = rev[i][j];\n flow[i][j] -= t; flow[k][ji] += t;\n if(!lim) break;\n }\n if(lim) level[i] = -1;\n return res;\n }\n\n S solve(int st_, int ed_){\n S res = 0;\n st = st_; ed = ed_;\n for(;;){\n levelize();\n if(level[ed] == -1) break;\n res += pushflow(st, numeric_limits<S>::max());\n }\n return res;\n }\n\n void init(int N){\n int i;\n node = N;\n rep(i,N) es[i] = 0;\n eps = (T)1e-9;\n }\n\n void memoryExpand(int i, int sz){\n if(sz <= emem[i]) return;\n sz = max(sz, max(3, emem[i]*2));\n emem[i]=sz;\n edge[i] = (int*)realloc(edge[i], sz*sizeof(int));\n rev[i] = (int*)realloc(rev[i], sz*sizeof(int));\n flow[i] = (T*)realloc(flow[i], sz*sizeof(T));\n }\n\n void addEdge(int n1, int n2, T f1, T f2 = 0){\n int s1 = es[n1]++, s2 = es[n2]++;\n if(s1 >= emem[n1]) memoryExpand(n1, es[n1]);\n if(s2 >= emem[n2]) memoryExpand(n2, es[n2]);\n edge[n1][s1]=n2; edge[n2][s2]=n1;\n flow[n1][s1]=f1; flow[n2][s2]=f2;\n rev[n1][s1]=s2; rev[n2][s2]=s1;\n }\n \n void addEdgeAdv(int n1, int n2, T f1, T f2 = 0){\n int s1 = es[n1]++, s2 = es[n2]++;\n edge[n1][s1]=n2; edge[n2][s2]=n1;\n flow[n1][s1]=f1; flow[n2][s2]=f2;\n rev[n1][s1]=s2; rev[n2][s2]=s1;\n }\n \n void setGraph(int N, int M, int n1[], int n2[], T f1[], T f2[]){\n int i;\n node = N;\n rep(i,N) es[i] = 0;\n rep(i,M) es[n1[i]]++, es[n2[i]]++;\n rep(i,N) memoryExpand(i, es[i]);\n rep(i,N) es[i] = 0;\n rep(i,M) addEdgeAdv(n1[i], n2[i], f1[i], f2[i]);\n eps = (T)1e-9;\n }\n\n void setGraph_w(int N, int M, int n1[], int n2[], T f1[], T f2[], void **mem = wmem){\n int i, j, k;\n node = N;\n rep(i,N) es[i] = emem[i] = 0;\n rep(i,M) es[n1[i]]++, es[n2[i]]++;\n \n edge[0] = (int*)(*mem);\n REP(i,1,N) edge[i] = edge[i-1] + es[i-1];\n rev[0] = edge[N-1] + es[N-1];\n REP(i,1,N) rev[i] = rev[i-1] + es[i-1];\n flow[0] = (T*)(rev[N-1] + es[N-1]);\n REP(i,1,N) flow[i] = flow[i-1] + es[i-1];\n *mem = (void*)(flow[N-1] + es[N-1]);\n \n rep(i,N) es[i] = 0;\n rep(i,M) addEdgeAdv(n1[i], n2[i], f1[i], f2[i]);\n eps = (T)1e-9;\n }\n};\n";
string p = "first";
vector<string> d;
d.push_back((string)"min_L");
d.push_back((string)"max_L");
d.push_back((string)"workmemory");
name.push_back(n); func[n] = c; need[n] = d; place[n] = p;
}
if(0){
string n = "";
string c = "";
string p = "first";
vector<string> d;
name.push_back(n);
func[n] = c;
need[n] = d;
place[n] = p;
}
doit.insert((string)"stdc");
doit.insert((string)"namespace");
}
string get_insert_string(string p){
int i, fg;
map<string,vector<string> >::iterator it;
vector<string> vs;
string res, tmp;
for(;;){
fg = 0;
for(it=need.begin(); it!=need.end(); it++){
tmp = it->first;
vs = it->second;
if(doit.count(tmp)==0 || g_flags.count("no-insert-"+tmp)) continue;
rep(i,vs.size()){
if(doit.count(vs[i])==0){
fg++;
doit.insert(vs[i]);
}
}
}
if(!fg) break;
}
rep(i,name.size()){
if(doit.count(name[i]) && g_flags.count("no-insert-"+name[i])==0 && already.count(name[i])==0 && place[name[i]] == p){
res += func[name[i]];
}
}
return res;
}
};
insertfunctions ifun;
struct code{
code *up;
vector<string> str, strtype;
vector<int> nxt;
vector<code*> nxtlst;
string name, type;
std::set<string> vartype, tvartype, tmp_vartype;
map<string,string> localvar, globalvar, argvar;
int insert_count;
void set_init(){
vartype.insert((string)"void");
vartype.insert((string)"char");
vartype.insert((string)"signed char");
vartype.insert((string)"unsigned char");
vartype.insert((string)"int");
vartype.insert((string)"signed int");
vartype.insert((string)"unsigned int");
vartype.insert((string)"signed");
vartype.insert((string)"unsigned");
vartype.insert((string)"long");
vartype.insert((string)"signed long");
vartype.insert((string)"unsigned long");
vartype.insert((string)"long long");
vartype.insert((string)"signed long long");
vartype.insert((string)"unsigned long long");
vartype.insert((string)"ll");
vartype.insert((string)"ull");
vartype.insert((string)"float");
vartype.insert((string)"double");
vartype.insert((string)"long double");
vartype.insert((string)"bool");
vartype.insert((string)"string");
vartype.insert((string)"mint");
vartype.insert((string)"combination_mint");
vartype.insert((string)"graph");
vartype.insert((string)"HLD");
tvartype.insert((string)"pair");
tvartype.insert((string)"vector");
tvartype.insert((string)"stack");
tvartype.insert((string)"queue");
tvartype.insert((string)"deque");
tvartype.insert((string)"priority_queue");
tvartype.insert((string)"set");
tvartype.insert((string)"map");
tvartype.insert((string)"unordered_set");
tvartype.insert((string)"unordered_map");
tvartype.insert((string)"segtree");
tvartype.insert((string)"maxflow");
tvartype.insert((string)"HLD_segtree");
}
void merge(std::set<string> &a, std::set<string> &b){
std::set<string>::iterator it;
for(it=b.begin();it!=b.end();it++){
a.insert(*it);
}
}
void merge(map<string,string> &a, map<string,string> &b){
map<string,string>::iterator it;
for(it=b.begin();it!=b.end();it++){
a[it->first] = it->second;
}
}
void set_next_types(std::set<string> &s_vartype, set<string> &s_tvartype, map<string,string> &s_localvar, map<string,string> &s_globalvar, map<string,string> &s_argvar){
merge(vartype, s_vartype);
merge(tvartype, s_tvartype);
merge(globalvar, s_globalvar);
merge(globalvar, s_localvar);
merge(globalvar, s_argvar);
}
void setUpnode(code *cc){
up = cc;
set_next_types(cc->vartype, cc->tvartype, cc->localvar, cc->globalvar, cc->argvar);
}
int is_empty_block(void){
int i, j;
int res = 1;
if(localvar.size()) res = 0;
if(nxtlst.size()) res = 0;
rep(i,str.size()) if(str[i]!=";") res = 0;
return res;
}
code* get_root(void){
code *r = this;
while(r->up != NULL) r = r->up;
return r;
}
pair<code*, string> find_struct(string in){
int i;
string tmp;
pair<code*, string> res;
res.first = NULL;
res.second = "";
rep(i,str.size()){
if(strtype[i] == "block-struct"){
tmp = str[i];
if(tmp == "struct " + in){
res.first = nxtlst[nxt[i]];
res.second = str[i];
return res;
}
}
if(strtype[i].substr(0,5) == "block"){
res = nxtlst[nxt[i]]->find_struct(in);
if(res.first != NULL) return res;
}
}
return res;
}
void add_vartype(string in){
int i;
vartype.insert(in);
rep(i,nxtlst.size()) nxtlst[i]->add_vartype(in);
}
void add_tvartype(string in){
int i;
tvartype.insert(in);
rep(i,nxtlst.size()) nxtlst[i]->add_tvartype(in);
}
void add_localvar(string in1, string in2){
int i;
code *cc = this;
while(cc->type == "block-inserted") cc = cc->up;
cc->localvar[in1] = in2;
rep(i,cc->nxtlst.size()) cc->nxtlst[i]->add_globalvar(in1, in2);
}
void add_globalvar(string in1, string in2){
int i;
globalvar[in1] = in2;
rep(i,nxtlst.size()) nxtlst[i]->add_globalvar(in1, in2);
}
void add_argvar(string in1, string in2){
int i;
argvar[in1] = in2;
rep(i,nxtlst.size()) nxtlst[i]->add_globalvar(in1, in2);
}
void ftrim(string &in){
while(in.size() && isspace(in[0])) in = in.substr(1);
}
void etrim(string &in){
while(in.size() && isspace(in[in.size()-1])) in = in.substr(0, in.size()-1);
}
void trim(string &in){
ftrim(in);
etrim(in);
}
void ftrim_until(string &in, char s){
while(in.size() && in[0] != s) in = in.substr(1);
}
void etrim_until(string &in, char t){
while(in.size() && in[in.size()-1] != t) in = in.substr(0, in.size()-1);
}
void trim_until(string &in, char s, char t){
ftrim_until(in,s);
etrim_until(in,t);
}
void code_replace(string &in){
int i, j, k, dot, dotp, d, dp, ex;
string str;
char buf[30];
ull val;
trim(in);
replaceAll_ns_t(in, "ll", "long long");
replaceAll_ns_t(in, "ull", "unsigned long long");
replaceAll_ns_t(in, "int_inf", "1073709056");
replaceAll_ns_t(in, "ll_inf", "4611686016279904256LL");
replaceAll_ns_t(in, "double_inf", "1e150");
if(strpos_ns_t(in, (string)"MD") >= 0) ifun.doit.insert((string)"define_MD");
if(strpos_ns_t(in, (string)"PI") >= 0) ifun.doit.insert((string)"define_PI");
if(strpos_ns_t(in, (string)"mint") >= 0) ifun.doit.insert((string)"mint");
if(strpos_ns_t(in, (string)"combination_mint") >= 0) ifun.doit.insert((string)"combination_mint");
if(strpos_ns_t(in, (string)"segtree") >= 0) ifun.doit.insert((string)"segtree");
if(strpos_ns_t(in, (string)"graph") >= 0) ifun.doit.insert((string)"graph");
if(strpos_ns_t(in, (string)"HLD") >= 0) ifun.doit.insert((string)"HLD");
if(strpos_ns_t(in, (string)"HLD_segtree") >= 0) ifun.doit.insert((string)"HLD_segtree");
if(strpos_ns_t(in, (string)"graph") >= 0) ifun.doit.insert((string)"graph");
if(strpos_ns_t(in, (string)"maxflow") >= 0) ifun.doit.insert((string)"maxflow");
for(;;){
int fg = 0;
rep(i,in.size()){
if(!isdigit(in[i])) continue;
if(i && isalnum(in[i-1])) continue;
dot = d = ex = 0;
REP(j,i,in.size()){
if(in[j]=='d'){ d++; dp=j; if(in[j+1]=='-' || in[j+1]=='+') j++; continue; }
if(in[j]=='.'){ dot++; dotp=j; continue; }
if(!isdigit(in[j])) break;
}
if(j < in.size() && isalpha(in[j])) continue;
if(dot > 1 || d != 1) continue;
if(dot && dotp > dp) continue;
str = in.substr(i, dp-i);
ex = atoi(in.c_str() + dp + 1);
if(ex > 30) ex = 30;
if(ex < -30) ex = -30;
while(ex > 0){
rep(k,str.size()) if(str[k]=='.') break;
if(k==str.size()){
str += '0';
} else if(k==str.size()-1) {
str[k] = '0';
} else {
str = str.substr(0,k) + str.substr(k+1,1) + "." + str.substr(k+2);
}
ex--;
}
while(ex < 0){
rep(k,str.size()) if(str[k]=='.') break;
if(k!=str.size()) str = str.substr(0, k);
if(str.size()) str = str.substr(0, str.size()-1);
ex++;
}
val = 0;
rep(k,str.size()){
if(str[k]=='.') break;
val = val * 10 + (str[k] - '0');
}
if(val < (1ULL << 31)){
sprintf(buf, "%llu", val);
} else if(val < (1ULL << 63)) {
sprintf(buf, "%lluLL", val);
} else {
sprintf(buf, "%lluULL", val);
}
str = buf;
in = in.substr(0,i) + str + in.substr(j);
fg = 1;
break;
}
if(!fg) break;
}
}
vector<string> split_p(string in, char c){
int i;
int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0;
vector<string> res;
string tmp;
rep(i,in.size()){
if(k4==0 && k5==0){
if(in[i]=='(') k1++;
if(in[i]==')') k1--;
if(in[i]=='[') k2++;
if(in[i]==']') k2--;
if(in[i]=='{') k3++;
if(in[i]=='}') k3--;
}
if(in[i]=='\'') k4 ^= 1;
if(in[i]=='"') k5 ^= 1;
if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0 && in[i]==c){
res.push_back(tmp);
tmp = "";
} else {
tmp += in[i];
}
}
res.push_back(tmp);
return res;
}
vector<string> split_p2(string in, char c){
int i;
int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0, k6 = 0;
vector<string> res;
string tmp;
rep(i,in.size()){
if(k4==0 && k5==0){
if(in[i]=='(') k1++;
if(in[i]==')') k1--;
if(in[i]=='[') k2++;
if(in[i]==']') k2--;
if(in[i]=='{') k3++;
if(in[i]=='}') k3--;
}
if(k2==0 && in[i]=='<') k6++;
if(k2==0 && in[i]=='>') k6--;
if(in[i]=='\'') k4 ^= 1;
if(in[i]=='"') k5 ^= 1;
if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0 && k6==0 && in[i]==c){
res.push_back(tmp);
tmp = "";
} else {
tmp += in[i];
}
}
res.push_back(tmp);
return res;
}
int isValidVarType(string in, char nxt){
int i, j, cnt;
if(isalnum(nxt)) return 0;
for(;;){
if(in.substr(0,6) == "const "){
in = in.substr(6);
ftrim(in);
continue;
}
if(in.substr(0,7) == "static "){
in = in.substr(7);
ftrim(in);
continue;
}
if(in.substr(0,10) == "inplace_L "){
in = in.substr(10);
ftrim(in);
continue;
}
break;
}
if(vartype.count(in) || tmp_vartype.count(in)) return 1;
rep(i,in.size()){
if(tvartype.count( in.substr(0,i) )){
cnt = 0;
REP(j,i,in.size()){
if(cnt==0 && isalnum(in[j])) break;
if(in[j]=='<') cnt++;
if(in[j]=='>') cnt--;
if(cnt==0 && in[j]=='>'){
j++;
if(j==in.size()) return 1;
if(in.substr(j) == "::iterator") return 1;
break;
}
}
}
}
return 0;
}
pair<string, char> nextToken(string &in){
int i, dig = 0;
string res1 = "";
char res2 = '\0';
i = 0;
while(i < in.size() && isspace(in[i])) i++;
if(i==in.size()) return make_pair(res1,res2);
if(isdigit(in[0]) || (in[0]=='.' && isdigit(in[1]))) dig = 1;
while(i < in.size() && (isalnum(in[i]) || in[i]=='.' || (!dig && in[i]=='_'))) res1 += in[i++];
// while(i < in.size() && (isalnum(in[i]) || (dig && in[i]=='.') || (!dig && in[i]=='_'))) res1 += in[i++];
while(i < in.size() && isspace(in[i])) i++;
res2 = in[i];
return make_pair(res1,res2);
}
pair<string,string> var_definition(string in){
int i, j, tt;
string type, name, pre, suf, eq;
vector<string> tmp;
rep(i,in.size()+1) if(isValidVarType(in.substr(0,i), in[i])) tt = i;
type = in.substr(0, tt);
in = in.substr(tt);
trim(in);
if(in[in.size()-1] == ';'){
in = in.substr(0, in.size()-1);
trim(in);
}
// fprintf(stderr, "[%s]\n", in.c_str());
tmp = split_p(in, '=');
assert(tmp.size() <= 2);
if(tmp.size()==2){
eq = tmp[1];
trim(eq);
eq = equation_main(eq);
in = tmp[0];
}
rep(i,in.size()) if(isalpha(in[i]) || in[i]=='_') break;
REP(j,i,in.size()) if(!(isalnum(in[j]) || in[j]=='_')) break;
name = in.substr(i, j-i);
pre = in.substr(0, i);
suf = in.substr(j);
trim(name);
trim(pre);
trim(suf);
return make_pair(name, type+","+pre+","+suf+","+eq);
}
string getElementalyVarType(string in){
int i, k;
vector<string> vs;
k = strpos(in, ".");
if(k >= 0){
string tp, res;
code *cc;
pair<code*,string> rs;
tp = getElementalyVarType( in.substr(0,k) );
in = in.substr(k+1);
trim(in);
if(tp == "graph"){
if(in=="es" || in=="edge" || in=="N") return "int";
return "error";
}
if(tp == "maxflow"){
// todo
}
cc = get_root();
rs = cc->find_struct(tp);
if(rs.first == NULL) return "error";
res = rs.first->getElementalyVarType( in);
return res;
}
while(in.size() && !isalpha(in[0])) in = in.substr(1);
if(in.size()==0) return (string)"error";
rep(i,in.size()) if(!isalnum(in[i])) break;
in = in.substr(0, i);
if(in == "MD") return "int";
if(in == "PI") return "double";
if(localvar.count(in)){
in = localvar[in];
} else if(argvar.count(in)){
in = argvar[in];
} else if(globalvar.count(in)){
in = globalvar[in];
} else {
return (string)"error";
}
vs = split_p(in, ',');
in = vs[0];
for(;;){
if(in.substr(0,6) == "const "){
in = in.substr(6);
ftrim(in);
continue;
}
if(in.substr(0,7) == "static "){
in = in.substr(7);
ftrim(in);
continue;
}
if(in.substr(0,10) == "inplace_L "){
in = in.substr(10);
ftrim(in);
continue;
}
break;
}
return in;
}
string getEquationType(string in){
int i;
int double_fg = 0, float_fg = 0, mint_fg = 0, ull_fg = 0, ll_fg = 0, unsigned_fg = 0, int_fg = 0, char_fg = 0, void_fg = 0;
pair<string,char> stchar;
string tp, str;
for(;;){
trim(in);
if(in.size()==0) break;
if(in[0] == '['){
i = pairBracket(in, 0);
if(i == -1) return (string)"error";
in = in.substr(i+1);
continue;
}
if(in[0] == '"'){
char_fg = 1;
for(i=1;;i++) if(in[i]=='"') break;
in = in.substr(i+1);
continue;
}
if(in[0] == '\''){
char_fg = 1;
for(i=1;;i++) if(in[i]=='\'') break;
in = in.substr(i+1);
continue;
}
stchar = nextToken(in);
str = stchar.first;
// fprintf(stderr,"[%s - %c]\n", stchar.first.c_str(), stchar.second);
in = in.substr(str.size());
if(str.size()==0) in = in.substr(1);
if(str.size()){
if(isdigit(str[0]) || (str[0]=='.' && isdigit(str[1]))) {
if(strpos(str, (string)".") >= 0 || strpos(str,(string)"e") >= 0){
if(str[str.size()-1] == 'f') tp = "float";
else tp = "double";
} else {
if(str.size() >= 2 && str.substr(str.size()-2) == "ll") tp = "long long";
else tp = "int";
}
} else if(isalpha(str[0])) {
tp = getElementalyVarType(str);
}
// fprintf(stderr, "%s\n",tp.c_str());
if(tp == "double") double_fg = 1;
if(tp == "float") float_fg = 1;
if(tp == "mint") mint_fg = 1;
if(tp == "long long") ll_fg = 1;
if(tp == "int") int_fg = 1;
if(tp == "char") char_fg = 1;
if(tp == "void") void_fg = 1;
}
}
if(double_fg) return (string)"double";
if(float_fg) return (string)"float";
if(mint_fg) return (string)"mint";
if(ull_fg) return (string)"unsigned long long";
if(ll_fg) return (string)"long long";
if(unsigned_fg) return (string)"unsigned";
if(int_fg) return (string)"int";
if(char_fg) return (string)"char";
if(void_fg) return (string)"void";
return (string)"error";
}
string getUnusedVarName(void){
int i, k, p, r;
string f = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
string res;
for(k=8;;k++) rep(p,100){
res = "";
r = rand()%52;
res += f[r];
REP(i,1,k){
r = rand()%f.size();
res += f[r];
}
if(localvar.count(res)) continue;
if(argvar.count(res)) continue;
if(globalvar.count(res)) continue;
return res;
}
return res;
}
void insert(string &in, int p){
int pure;
for(;;){
ftrim(in);
if(in.size()==0) break;
insert_count++;
if(in[0]=='{') pure = 1; else pure = 0;
code *cc = new code;
cc->setUpnode(this);
if(pure){
cc->set(in, (string)"block");
} else {
cc->set(in, (string)"block-inserted");
}
nxt.insert(nxt.begin()+p, nxtlst.size());
nxtlst.push_back(cc);
str.insert(str.begin()+p, (string)"");
if(pure){
strtype.insert(strtype.begin()+p, (string)"block");
} else {
strtype.insert(strtype.begin()+p, (string)"block-inserted");
}
p++;
}
}
int strpos(string &A, string B, int st = 0){
int i, As, Bs;
As = A.size();
Bs = B.size();
REP(i,st,As-Bs+1) if(A.substr(i,Bs) == B) return i;
return -1;
}
int strpos_ns(string &A, string B, int st = 0){ // "", '' の中は検索対象外
int i, k4, k5, As, Bs;
As = A.size();
Bs = B.size();
k4 = k5 = 0;
REP(i,st,As-Bs+1){
if( (k4 || k5) && A[i] == '\\' ){i++; continue;}
if(A[i] == '"') k4 ^= 1;
if(A[i] == '\'') k5 ^= 1;
if(k4==0 && k5==0 && A.substr(i,Bs) == B) return i;
}
return -1;
}
int strrpos_ns(string &A, string B, int st = -1){
int i, k4, k5, As, Bs;
As = A.size();
Bs = B.size();
k4 = k5 = 0;
if(st == -1) st = As-Bs+1;
for(i=st;i>=0;i--){
if( (k4 || k5) && A[i] == '\\' ){i++; continue;}
if(A[i] == '"') k4 ^= 1;
if(A[i] == '\'') k5 ^= 1;
if(k4==0 && k5==0 && A.substr(i,Bs) == B) return i;
}
return -1;
}
int strpos_t(string &A, string B, int st = 0){
int i, As, Bs;
As = A.size();
Bs = B.size();
REP(i,st,As-Bs+1) if(A.substr(i,Bs) == B){
if(i && (isalnum(A[i-1]) || A[i-1]=='_')) continue;
if(i+Bs<As && (isalnum(A[i+Bs]) || A[i+Bs]=='_')) continue;
return i;
}
return -1;
}
int strpos_ns_t(string &A, string B, int st = 0){
int i, k4, k5, As, Bs;
As = A.size();
Bs = B.size();
k4 = k5 = 0;
REP(i,st,As-Bs+1){
if( (k4 || k5) && A[i] == '\\' ){i++; continue;}
if(A[i] == '"') k4 ^= 1;
if(A[i] == '\'') k5 ^= 1;
if(k4==0 && k5==0 && A.substr(i,Bs) == B){
if(i && (isalnum(A[i-1]) || A[i-1]=='_')) continue;
if(i+Bs<As && (isalnum(A[i+Bs]) || A[i+Bs]=='_')) continue;
return i;
}
}
return -1;
}
int replaceAll(string &A, string B, string C){
int i, res = 0;
for(;;){
i = strpos(A, B);
if(i==-1) break;
A = A.substr(0, i) + C + A.substr(i+B.size());
}
return res;
}
int replaceAll_ns(string &A, string B, string C){
int i, res = 0;
for(;;){
i = strpos_ns(A, B);
if(i==-1) break;
A = A.substr(0, i) + C + A.substr(i+B.size());
}
return res;
}
int replaceAll_t(string &A, string B, string C){
int i, res = 0;
for(;;){
i = strpos_t(A, B);
if(i==-1) break;
A = A.substr(0, i) + C + A.substr(i+B.size());
}
return res;
}
int replaceAll_ns_t(string &A, string B, string C){
int i, res = 0;
for(;;){
i = strpos_ns_t(A, B);
if(i==-1) break;
A = A.substr(0, i) + C + A.substr(i+B.size());
}
return res;
}
vector<string> rd_wt_array(string in){ // 1+((a,b)(N)+2) returns "1+(", "(a,b)", "N", "+2)", hoge returns "hoge"
int i, j, k, bf = -1, fg;
string chk;
vector<string> res;
rep(i,in.size()){
fg = 0;
if(bf == ')' || bf == ']') fg = 1;
if(isalnum(bf) && in[i] == '('){
if(localvar.count(chk) || globalvar.count(chk) || argvar.count(chk)) fg = 1;
if(getElementalyVarType(chk) != "error") fg = 1;
}
if(fg && in[i] == '('){
rep(k,4) res.push_back((string)"");
j = pairBracket(in, i);
res[2] = in.substr(i+1, j-i-1);
res[3] = in.substr(j+1);
in = in.substr(0, i);
trim(in);
i = in.size() - 1;
while(in[i] == ']'){
i = pairBracket(in, i) - 1;
while(isspace(in[i])) i--;
}
if(in[i]==')'){
i = pairBracket(in, i);
res[0] = in.substr(0, i);
res[1] = in.substr(i);
} else {
while(i >= 0 && (isalnum(in[i]) || in[i]=='_' || in[i]=='@' || in[i]=='.')) i--;
i++;
res[0] = in.substr(0, i);
res[1] = in.substr(i);
}
rep(k,4) trim(res[k]);
return res;
}
if(!isspace(in[i])){
bf = in[i];
if(isalnum(bf) || bf=='.' || bf=='_') chk += bf;
else chk = "";
}
}
res.push_back(in);
return res;
}
int checkBracketsCoressponding(string &in){
int i;
int k4, k5;
stack<int> s;
k4 = k5 = 0;
rep(i,in.size()){
if(k4==0 && k5==0){
if(in[i] == '(') s.push(1);
if(in[i] == '[') s.push(2);
if(in[i] == '{') s.push(3);
if(in[i] == ')'){
if(s.size()==0 || s.top()!=1) return 0;
s.pop();
}
if(in[i] == ']'){
if(s.size()==0 || s.top()!=2) return 0;
s.pop();
}
if(in[i] == '}'){
if(s.size()==0 || s.top()!=3) return 0;
s.pop();
}
}
if(in[i] == '\'') k4^=1;
if(in[i] == '"') k5^=1;
}
if(k4 || k5 || s.size()) return 0;
return 1;
}
int pairBracket(string &in, int p){
int i;
int k1, k2, k3, k4, k5;
k1 = k2 = k3 = k4 = k5 = 0;
if(in[p]=='(' || in[p]=='[' || in[p]=='{'){
for(i=p;i<in.size();i++){
if(k4==0 && k5==0){
if(in[i] == '(') k1++;
if(in[i] == ')') k1--;
if(in[i] == '[') k2++;
if(in[i] == ']') k2--;
if(in[i] == '{') k3++;
if(in[i] == '}') k3--;
}
if(in[i] == '\'') k4^=1;
if(in[i] == '"') k5^=1;
if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0) return i;
}
} else if(in[p]==')' || in[p]==']' || in[p]=='}'){
for(i=p;i>=0;i--){
if(k4==0 && k5==0){
if(in[i] == '(') k1++;
if(in[i] == ')') k1--;
if(in[i] == '[') k2++;
if(in[i] == ']') k2--;
if(in[i] == '{') k3++;
if(in[i] == '}') k3--;
}
if(in[i] == '\'') k4^=1;
if(in[i] == '"') k5^=1;
if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0) return i;
}
}
return -1;
}
/* in = bb + argmin[hoge](piyo) + aa; */
/* format = argmin[]() */
/* return {"bb + ", "hoge", "piyo", " + aa;"} */
/* if not found -> return {} */
vector<string> findFunction(string &in, string format){
int i, j, k, m, ok;
int k4, k5;
vector<string> fmt;
vector<string> res;
for(;;){
string tmp;
trim(format);
if(format.size()==0) break;
if(format.substr(0,2) == "()" || format.substr(0,2) == "[]"){
fmt.push_back(format.substr(0,2));
format = format.substr(2);
continue;
}
tmp = "";
while(format.size() && (isalnum(format[0]) || format[0]=='_')){
tmp += format[0];
format = format.substr(1);
}
if(tmp == ""){
tmp += format[0];
format = format.substr(1);
}
fmt.push_back(tmp);
}
k4 = k5 = 0;
rep(i,in.size()){
if(in[i] == '"'){ k4 ^= 1; continue; }
if(in[i] == '\''){ k5 ^= 1; continue; }
if(k4 || k5){
if(in[i] == '\\') i++;
continue;
}
if(i && (isalnum(fmt[0][0]) || fmt[0][0]=='_') && (isalnum(in[i-1]) || in[i-1]=='_')) continue;
res.clear();
res.push_back( in.substr(0, i) );
j = i;
ok = 1;
rep(k,fmt.size()){
if(fmt[k] == "()"){
if(in[j]!='('){ ok = 0; break; }
m = pairBracket(in, j);
res.push_back( in.substr(j+1, m-j-1) );
j = m + 1;
while(j < in.size() && isspace(in[j])) j++;
continue;
}
if(fmt[k] == "[]"){
if(in[j]!='['){ ok = 0; break; }
m = pairBracket(in, j);
res.push_back( in.substr(j+1, m-j-1) );
j = m + 1;
while(j < in.size() && isspace(in[j])) j++;
continue;
}
while(j < in.size() && isspace(in[j])) j++;
if(in.substr(j, fmt[k].size()) == fmt[k]){
j += fmt[k].size();
} else {
ok = 0;
break;
}
}
if(ok){
res.push_back( in.substr(j) );
return res;
}
}
res.clear();
return res;
}
int getExprLength_firstind(string tmp, int k){
int i;
tmp = tmp.substr(k);
k = 0;
for(;;){
if(k==tmp.size()) break;
if(isspace(tmp[k])){ k++; continue; }
if(isOperator(tmp[k])){ k++; continue; }
if(tmp[k]=='('){
i = pairBracket(tmp, k);
if(isValidVarType(tmp.substr(k+1, i-k-1), ' ')){
k = i + 1;
continue;
}
}
break;
}
while(k < tmp.size() && (isalnum(tmp[k]) || tmp[k]=='.')) k++;
for(;;){
while(k < tmp.size() && isspace(tmp[k])) k++;
if(k==tmp.size()) break;
if(tmp[k]=='('){
k = pairBracket(tmp, k) + 1;
tmp = tmp.substr(0, k);
break;
}
if(tmp[k]=='['){
k = pairBracket(tmp, k) + 1;
continue;
}
tmp = tmp.substr(0, k);
break;
}
return tmp.size();
}
int getExprLength_lastind(string tmp, int k){
int i;
tmp = tmp.substr(0, k+1);
for(;;){
if(k >= 0 && isspace(tmp[k])){ k--; continue; }
if(tmp[k]==']'){
k = pairBracket(tmp, k) - 1;
continue;
}
break;
}
if(tmp[k] == ')'){
k = pairBracket(tmp, k) - 1;
} else if((isalnum(tmp[k]) || tmp[k]=='.')){
while(k >= 0 && (isalnum(tmp[k]) || tmp[k]=='.')) k--;
}
tmp = tmp.substr(k+1);
return tmp.size();
}
string sentence_hatena_minmax_operator(string tmp){
int i, j;
int k1, k2, k3, k4, k5;
int p, p1, p2;
string mode, arg1, arg2, bef, aft;
for(;;){
p1 = strpos_ns(tmp, (string)">?=");
p2 = strpos_ns(tmp, (string)"<?=");
if(p1<0 && p2<0) break;
if(p1 > p2) p = p1, mode = "chmax";
else p = p2, mode = "chmin";
ifun.doit.insert(mode);
k1 = k2 = k3 = k4 = k5 = 0;
for(i=p-1;;i--){
if(i >= 1 && k4 && tmp[i-1]=='/' && tmp[i]=='\''){ i-=2; continue; }
if(i >= 0 && tmp[i]=='\'') k4 ^= 1;
if(i >= 0 && tmp[i]=='"') k5 ^= 1;
if(i >= 0 && k4==0 && k5==0){
if(tmp[i]==')') k1++;
if(tmp[i]=='(') k1--;
if(tmp[i]=='}') k2++;
if(tmp[i]=='{') k2--;
if(tmp[i]==']') k3++;
if(tmp[i]=='[') k3--;
}
if(i==-1 || tmp[i] == '=' || tmp[i] == ','){
aft = "";
bef = tmp.substr(0, i+1);
arg1 = tmp.substr(i+1,p-(i+1));
arg2 = tmp.substr(p+3);
arg2 = arg2.substr(0, arg2.size()-1);
} else if(k1 < 0 || k2 < 0 || k3 < 0){
j = pairBracket(tmp, i);
bef = tmp.substr(0, i+1);
arg1 = tmp.substr(i+1, p-(i+1));
arg2 = tmp.substr(p+3, j-(p+3));
aft = tmp.substr(j);
aft = aft.substr(0, aft.size()-1);
} else {
continue;
}
trim(bef);
trim(aft);
trim(arg1);
trim(arg2);
tmp = bef + mode + "(" + arg1 + ", " + arg2 + ")" + aft + ";";
break;
}
}
return tmp;
}
string sentence_inequation(string tmp){
int i, j, k, ls = 0, ok;
int k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0;
string send, recv, tmp2;
vector<string> vs, vs2;
rep(i,tmp.size()){
k = -1;
REP(j,1,tmp.size()-i){
if(j>100) break;
if(isValidVarType(tmp.substr(i,j), tmp[i+j])) k = j;
}
if(k > 0){
i += k-1;
continue;
}
if(tmp[i]=='<'){
int k6 = 0;
REP(j,i,tmp.size()){
if(tmp[j] == '<') k6++;
if(tmp[j] == '>') k6--;
if(k6==0) break;
}
if(j<tmp.size()){
j++;
tmp2 = tmp.substr(i+1, j-i-2);
trim(tmp2);
vs2 = split_p(tmp2, ',');
ok = 0;
rep(k,vs2.size()){
trim(vs2[k]);
if(isValidVarType(vs2[k], ' ')) ok++;
}
if(ok){
i = j;
continue;
}
}
}
if( (k4 || k5) && tmp[i]=='\\' ){ i++; continue; }
if(k4==0 && k5==0){
if(tmp[i]=='(') k1++;
if(tmp[i]==')') k1--;
if(tmp[i]=='[') k2++;
if(tmp[i]==']') k2--;
if(tmp[i]=='{') k3++;
if(tmp[i]=='}') k3--;
}
if(tmp[i]=='\'') k4 ^= 1;
if(tmp[i]=='"') k5 ^= 1;
if(k1 == 0 && k2 == 0 & k3 == 0 && k4 == 0 && k5 == 0){
if(tmp.substr(i,2) == "->"){ i++; continue; }
if(tmp.substr(i,2) == ">>"){ i++; continue; }
if(tmp.substr(i,2) == "<<"){ i++; continue; }
if(tmp.substr(i,2) == ">=" || tmp.substr(i,2) == "<=" || tmp.substr(i,2) == "==" || tmp.substr(i,2) == "||" || tmp.substr(i,2) == "&&"){
if(ls < i){
vs.push_back( tmp.substr(ls, i-ls) );
ls = i;
}
i++;
vs.push_back( tmp.substr(ls, i+1-ls) );
ls = i+1;
continue;
}
if(tmp[i]=='<' || tmp[i]=='>' || tmp[i]==';' || tmp[i]==':' || tmp[i]=='?'){
if(ls < i){
vs.push_back( tmp.substr(ls, i-ls) );
ls = i;
}
vs.push_back( tmp.substr(ls, i+1-ls) );
ls = i+1;
continue;
}
}
}
i = tmp.size();
if(ls < i){
vs.push_back( tmp.substr(ls, i-ls) );
ls = i;
}
tmp = "";
rep(i,vs.size()){
if(vs[i]=="<" || vs[i]==">" || vs[i]=="<=" || vs[i]==">="){
if(i-2>=0 && (vs[i-2]=="<" || vs[i-2]==">" || vs[i-2]=="<=" || vs[i-2]==">=")){
tmp += " && " + vs[i-1];
}
}
tmp += vs[i];
}
rep(i,tmp.size()){
if( (k4 || k5) && tmp[i]=='\\' ){ i++; continue; }
if(k4==0 && k5==0){
if(tmp[i]=='(') k1++;
if(tmp[i]==')') k1--;
if(tmp[i]=='[') k2++;
if(tmp[i]==']') k2--;
if(tmp[i]=='{') k3++;
if(tmp[i]=='}') k3--;
}
if(tmp[i]=='\'') k4 ^= 1;
if(tmp[i]=='"') k5 ^= 1;
if(k1==1 && k2==0 && k3==0 && k4==0 && k5==0 && tmp[i]=='('){
j = pairBracket(tmp, i);
send = tmp.substr(i+1, j-i-1);
recv = sentence_inequation(send);
tmp = tmp.substr(0, i+1) + recv + tmp.substr(j);
}
if(k1==0 && k2==1 && k3==0 && k4==0 && k5==0 && tmp[i]=='['){
j = pairBracket(tmp, i);
send = tmp.substr(i+1, j-i-1);
recv = sentence_inequation(send);
tmp = tmp.substr(0, i+1) + recv + tmp.substr(j);
}
if(k1==0 && k2==0 && k3==1 && k4==0 && k5==0 && tmp[i]=='{'){
j = pairBracket(tmp, i);
send = tmp.substr(i+1, j-i-1);
recv = sentence_inequation(send);
tmp = tmp.substr(0, i+1) + recv + tmp.substr(j);
}
}
return tmp;
}
string sentence_times_operator(string tmp){
int i, j, k, ok;
int k1, k2;
string now;
pair<string,char> stchar;
for(;;){
int fg = 0;
k1 = k2 = 0;
now = "";
rep(i,tmp.size()){
ok = 1;
if((k1 || k2) && tmp[i]=='\\'){ i++; continue; }
if(k2==0 && tmp[i]=='"') k1 ^= 1;
if(k1==0 && tmp[i]=='\'') k2 ^= 1;
if(k1 || k2) continue;
if(isalnum(tmp[i]) || tmp[i]=='_' || tmp[i]=='.') now += tmp[i];
else now = "";
if(now[0]=='.' && !isdigit(now[1])) ok = 0;
if(!isdigit(now[0]) && now[0]!='.') ok = 0;
if((tmp[i+1]=='d' || tmp[i+1]=='e' || tmp[i+1]=='D' || tmp[i+1]=='E') && (isdigit(tmp[i+2])||tmp[i+2]=='-')) ok = 0;
if(tmp.substr(i+1,1)=="u" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,1)=="U" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,1)=="l" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,1)=="L" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,1)=="f" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,1)=="F" && (!isalnum(tmp[i+2]) && tmp[i+2]!='_')) ok = 0;
if(tmp.substr(i+1,2)=="ll" && (!isalnum(tmp[i+3]) && tmp[i+3]!='_')) ok = 0;
if(tmp.substr(i+1,2)=="LL" && (!isalnum(tmp[i+3]) && tmp[i+3]!='_')) ok = 0;
if(tmp.substr(i+1,3)=="ull" && (!isalnum(tmp[i+4]) && tmp[i+4]!='_')) ok = 0;
if(tmp.substr(i+1,3)=="ULL" && (!isalnum(tmp[i+4]) && tmp[i+4]!='_')) ok = 0;
j = i + 1;
while(j < tmp.size() && isspace(tmp[j])) j++;
if(j==i+1 && (isdigit(tmp[j]) || tmp[j]=='.')) ok = 0;
if(!(isalnum(tmp[j]) || tmp[j]=='_' || tmp[j]=='.' || tmp[j]=='(')) ok = 0;
if(ok){
tmp = tmp.substr(0,i+1) + "*" + tmp.substr(i+1);
fg = 1;
break;
}
}
if(!fg) break;
}
return tmp;
}
string sentence_pow_operator(string tmp){
int i, j, k, st = 0;
int bi, bj, ei, ej;
int len_i, len_j;
string bef, t1, t2, aft;
while(strpos_ns(tmp, (string)"**", st) >= 0){
k = strpos_ns(tmp, (string)"**", st);
st = k+1;
i = k-1;
while(i >= 0 && isspace(tmp[i])) i--;
if(i < 0 || isOperator(tmp[i])) continue;
for(j=i;j>=0&&j>=i-100;j--) if(isValidVarType(tmp.substr(j,i-j+1),tmp[i+1])) break;
if(j>=0 && j>=i-100) continue;
j = k+2;
while(j < tmp.size() && isspace(tmp[j])) j++;
if(j == tmp.size()) continue;
len_i = getExprLength_lastind(tmp, i);
len_j = getExprLength_firstind(tmp, j);
bi = i - len_i + 1;
ei = i;
bj = j;
ej = j + len_j - 1;
bef = tmp.substr(0, bi);
t1 = tmp.substr(bi, ei-bi+1);
t2 = tmp.substr(bj, ej-bj+1);
aft = tmp.substr(ej+1);
trim(t1);
trim(t2);
if(t2 == "2"){
tmp = bef + "pow2_L(" + t1 + ")" + aft;
ifun.doit.insert((string)"pow2");
} else if(t2 == "3"){
tmp = bef + "pow3_L(" + t1 + ")" + aft;
ifun.doit.insert((string)"pow3");
} else if(t2 == "4"){
tmp = bef + "pow4_L(" + t1 + ")" + aft;
ifun.doit.insert((string)"pow4");
} else {
tmp = bef + "pow_L(" + t1 + "," + t2 + ")" + aft;
ifun.doit.insert((string)"pow");
}
st = 0;
}
return tmp;
}
string sentence_div_operator(string tmp){
int i, j, k, st = 0;
int bi, bj, ei, ej;
int len_i, len_j;
string bef, t1, t2, aft;
while(strpos_ns(tmp, (string)"/+", st) >= 0){
k = strpos_ns(tmp, (string)"/+", st);
st = k+1;
i = k-1;
while(i >= 0 && isspace(tmp[i])) i--;
if(i < 0 || isOperator(tmp[i])) continue;
j = k+2;
while(j < tmp.size() && isspace(tmp[j])) j++;
if(j == tmp.size()) continue;
len_i = getExprLength_lastind(tmp, i);
len_j = getExprLength_firstind(tmp, j);
bi = i - len_i + 1;
ei = i;
bj = j;
ej = j + len_j - 1;
bef = tmp.substr(0, bi);
t1 = tmp.substr(bi, ei-bi+1);
t2 = tmp.substr(bj, ej-bj+1);
aft = tmp.substr(ej+1);
trim(t1);
trim(t2);
tmp = bef + "divup_L(" + t1 + "," + t2 + ")" + aft;
ifun.doit.insert((string)"divup");
st = 0;
}
return tmp;
}
string sentence_minmax_function(string tmp, int blocked = 1){
int i, j, k, nv, mode;
string tp, cd, var, bg, ed, eqn, ieq, indvar;
vector<string> vs, unusedname, vararr, tmpvs;
for(;;){
vs.clear();
if(vs.size()==0){
vs = findFunction(tmp, "min[]()");
if(vs.size() == 4) ieq = ">", mode = 0;
}
if(vs.size()==0){
vs = findFunction(tmp, "max[]()");
if(vs.size() == 4) ieq = "<", mode = 0;
}
if(vs.size()==0){
vs = findFunction(tmp, "argmin[]()");
if(vs.size() == 4) ieq = ">", mode = 1;
}
if(vs.size()==0){
vs = findFunction(tmp, "argmax[]()");
if(vs.size() == 4) ieq = "<", mode = 1;
}
if(vs.size()==0){
vs = findFunction(tmp, "argminL[]()");
if(vs.size() == 4) ieq = ">=", mode = 1;
}
if(vs.size()==0){
vs = findFunction(tmp, "argmaxL[]()");
if(vs.size() == 4) ieq = "<=", mode = 1;
}
if(vs.size()==0) break;
tp = getEquationType(vs[2]);
vararr = split_p(vs[1], ',');
nv = vararr.size();
unusedname.clear();
rep(i,nv+3) unusedname.push_back( getUnusedVarName() );
indvar = getUnusedVarName();
if(blocked) cd += "{";
cd += "int " + unusedname[0];
REP(i,1,nv) cd += ", " + unusedname[i];
cd += ", " + unusedname[nv] + " = 0;";
cd += tp + " " + unusedname[nv+1] + ", " + unusedname[nv+2] + ";";
if(mode) cd += "int " + indvar + ";";
eqn = vs[2];
rep(i,nv){
tmpvs = split_p(vararr[i], '=');
var = tmpvs[0];
j = strpos_ns(tmpvs[1], "---");
assert(j >= 0);
bg = tmpvs[1].substr(0, j);
ed = tmpvs[1].substr(j+3);
cd += "rep(" + unusedname[i] + ", " + bg + ", (" + ed +")+1) ";
replaceAll_ns_t(eqn, var, unusedname[i]);
}
cd += "{";
cd += unusedname[nv+2] + " = " + eqn + ";";
cd += "if(" + unusedname[nv] + "==0 || " + unusedname[nv+1] + ieq + unusedname[nv+2] + "){";
cd += unusedname[nv+1] + " = " + unusedname[nv+2] + ";";
cd += unusedname[nv] + " = 1;";
if(mode) cd += indvar + " = " + unusedname[0] + ";";
cd += "}";
cd += "}";
if(blocked){
if(mode==0) cd += vs[0] + unusedname[nv+1] + vs[3];
if(mode==1) cd += vs[0] + indvar + vs[3];
cd += "}";
insert(cd, str.size());
return "";
} else {
insert(cd, str.size());
if(mode==0) tmp = vs[0] + unusedname[nv+1] + vs[3];
if(mode==1) tmp = vs[0] + indvar + vs[3];
}
}
return tmp;
}
string sentence_reader(string tmp){
int i, j, k;
pair<string, char> stchar;
vector<string> vtmp, vvtmp;
string at, stmp;
stchar = nextToken(tmp);
if( (stchar.first == "rd" || stchar.first == "reader") && stchar.second == '(' ){
trim_until(tmp, '(', ')');
tmp = tmp.substr(1,tmp.size()-2);
vtmp = split_p(tmp, ',');
rep(k,vtmp.size()){
trim(vtmp[k]);
string stc;
string strtmp;
vector<string> vstrtmp;
strtmp = vtmp[k];
trim(strtmp);
vstrtmp = rd_wt_array(strtmp);
if(vstrtmp.size() > 1){
string vn = getUnusedVarName(), var;
vector<string> vars;
if(vstrtmp[1][0]=='('){
vstrtmp[1] = vstrtmp[1].substr(1, vstrtmp[1].size()-2);
vars = split_p(vstrtmp[1], ',');
} else {
vars.push_back(vstrtmp[1]);
}
var = "";
rep(j,vars.size()){
if(j) var += ", ";
trim(vars[j]);
vvtmp = split_p(vars[j], '@');
stmp = "";
rep(i,vvtmp.size()){
if(i) stmp += (string)"@";
stmp += vvtmp[i] + "[" + vn + "]";
}
var += vstrtmp[0] + stmp + vstrtmp[3];
}
stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") rd(" + var + "); }";
insert(stc, str.size());
} else {
vvtmp = split_p(vstrtmp[0], '@');
at = "";
if(vvtmp.size()>=2){
vstrtmp[0] = vvtmp[0];
at = vvtmp[1];
trim(vstrtmp[0]);
trim(at);
}
string etype = getElementalyVarType(vstrtmp[0]);
// fprintf(stderr, "type estimation: [%s] [%s]\n",etype.c_str(), vstrtmp[0].c_str());
if(etype=="int"){
ifun.doit.insert((string)"reader_int");
} else if(etype=="long long"){
ifun.doit.insert((string)"reader_ll");
} else if(etype=="mint"){
ifun.doit.insert((string)"reader_mint");
} else if(etype=="double"){
ifun.doit.insert((string)"reader_double");
} else if(etype=="char"){
ifun.doit.insert((string)"reader_char_array");
} else {
fprintf(stderr, "unknown type [%s] for rd (reader) : %s\n", etype.c_str(), vtmp[k].c_str());
assert(0);
}
if(at!="") stc = at + " = rd(" + vstrtmp[0] + ");";
else stc = (string)"rd(" + vstrtmp[0] + ");";
str.push_back(stc);
nxt.push_back(-1);
strtype.push_back((string)"sentence");
}
}
return "";
}
return tmp;
}
string sentence_writer(string tmp){
int i, j, k;
string mode;
pair<string, char> stchar;
vector<string> vtmp;
stchar = nextToken(tmp);
if( (stchar.first == "wt" || stchar.first == "writer" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wt";
if( (stchar.first == "wtSp" || stchar.first == "writerSp") && (stchar.second == '[' || stchar.second == '(') ) mode = "wtSp";
if( (stchar.first == "wtLn" || stchar.first == "writerLn") && (stchar.second == '[' || stchar.second == '(') ) mode = "wtLn";
if( (stchar.first == "wtN" || stchar.first == "writerN" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wtN";
if( (stchar.first == "wtF" || stchar.first == "writerF" ) && (stchar.second == '[' || stchar.second == '(') ) mode = "wtF";
if(mode=="") return tmp;
string optarg = "", basestr = "";
if(stchar.second == '['){
int ss, tt;
string stmp; vector<string> vtmp1, vtmp2;
pair<string,char> ctmp;
ss = strpos(tmp, "[");
tt = pairBracket(tmp, ss);
optarg = tmp.substr(ss, tt-ss+1);
tmp = tmp.substr(tt+1);
stmp = optarg.substr(1, optarg.size()-2);
vtmp1 = split_p(stmp, ',');
rep(k,vtmp1.size()){
trim(vtmp1[k]);
ctmp = nextToken(vtmp1[k]);
if(ctmp.first == "B" && ctmp.second == '='){
vtmp2 = split_p(vtmp1[k], '=');
trim(vtmp2[1]);
basestr = "," + vtmp2[1];
}
}
}
trim_until(tmp, '(', ')');
tmp = tmp.substr(1,tmp.size()-2);
if(mode == "wtF"){
string wstr, estr, cstr;
trim_until(tmp, '"', '"');
tmp = tmp.substr(1, tmp.size() - 2);
i = k = 0;
rep(i,tmp.size()){
if(tmp[i]=='{'){
if(wstr.size()) cstr += (string)"wtN(\"" + wstr + "\");\n";
wstr = "";
k = 1;
continue;
}
if(tmp[i]=='}'){
if(estr.size()) cstr += (string)"wtN(" + estr + ");\n";
estr = "";
k = 0;
continue;
}
if(tmp[i]=='\\' && (tmp[i+1]=='{' || tmp[i+1]=='}')) i++;
if(k==0) wstr += tmp[i];
else estr += tmp[i];
}
if(wstr.size()) cstr += (string)"wtN(\"" + wstr + "\");\n";
if(estr.size()) cstr += (string)"wtN(" + estr + ");\n";
insert(cstr, str.size());
} else {
vtmp = split_p(tmp, ',');
rep(k,vtmp.size()){
trim(vtmp[k]);
string etype = getEquationType(vtmp[k]);
string stc;
if(etype=="int"){
if(basestr=="") ifun.doit.insert((string)"writer_int");
else ifun.doit.insert((string)"writer_int_withBase");
} else if(etype=="long long"){
if(basestr=="") ifun.doit.insert((string)"writer_ll");
else ifun.doit.insert((string)"writer_ll_withBase");
} else if(etype=="mint"){
ifun.doit.insert((string)"writer_mint");
} else if(etype=="double"){
ifun.doit.insert((string)"writer_double");
} else if(etype=="char"){
ifun.doit.insert((string)"writer_char_array");
} else {
fprintf(stderr, "unknown type [%s] for wt (writer) : %s\n", etype.c_str(), vtmp[k].c_str());
assert(0);
}
string strtmp;
vector<string> vstrtmp;
strtmp = vtmp[k];
trim(strtmp);
vstrtmp = rd_wt_array(strtmp);
if(vstrtmp.size() > 1){
string vn = getUnusedVarName(), var;
if(vstrtmp[1][0]=='('){
vector<string> vars;
vstrtmp[1] = vstrtmp[1].substr(1, vstrtmp[1].size()-2);
vars = split_p(vstrtmp[1], ',');
var = "";
rep(j,vars.size()){
if(j) var += ", ";
trim(vars[j]);
var += vstrtmp[0] + vars[j] + "[" + vn + "]" + vstrtmp[3];
}
} else {
var = vstrtmp[0] + vstrtmp[1] + "[" + vn + "]" + vstrtmp[3];
}
if(mode == "wt"){
if(k==vtmp.size()-1){
stc = (string)"{\n int "+vn+";\n if("+vstrtmp[2]+"==0) putchar_unlocked('\\n');\n else {\n rep("+vn+","+vstrtmp[2]+"-1) wtSp" + optarg + "("+var+");\n wt" + optarg + "("+var+");\n }\n}";
} else {
stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") wtSp" + optarg + "(" + var + "); }";
}
} else {
stc = (string)"{ int " + vn + "; rep(" + vn + "," + vstrtmp[2] + ") " + mode + optarg + "(" + var + "); }";
}
insert(stc, str.size());
} else {
if(etype=="int" || etype=="long long") vstrtmp[0] += basestr;
stc = (string)"wt_L(" + vstrtmp[0] + ");";
str.push_back(stc);
nxt.push_back(-1);
strtype.push_back((string)"sentence");
stc = "";
if(mode == "wtLn" || (mode=="wt" && k==vtmp.size()-1)){
stc = (string)"putchar_unlocked('\\n');";
}
if(mode == "wtSp" || (mode=="wt" && k!=vtmp.size()-1)){
stc = (string)"putchar_unlocked(' ');";
}
if(stc != ""){
str.push_back(stc);
nxt.push_back(-1);
strtype.push_back((string)"sentence");
}
}
}
}
return "";
}
string sentence_dot_loop(string tmp){
int k, pl, pb, pa, fg = 0;
int k1, k2, k3, k4, k5;
string dots = "..";
string vn, stc, bg, ed, fbg, fed;
if(strpos_ns(tmp, (string)"..") == -1) return tmp;
while(strpos_ns(tmp, dots) >= 0) dots += ".";
dots = dots.substr(1);
vn = getUnusedVarName();
stc = "";
stc += (string)"{ int " + vn + ";";
for(;;){
pl = strpos_ns(tmp, dots);
if(pl<0) break;
k1 = k2 = k3 = k4 = k5 = 0;
for(k=pl-1;k>=0;k--){
if(k4==0 && k5==0){
if(tmp[k] == '(') k1++;
if(tmp[k] == ')') k1--;
if(tmp[k] == '[') k2++;
if(tmp[k] == ']') k2--;
if(tmp[k] == '{') k3++;
if(tmp[k] == '}') k3--;
}
if(tmp[k] == '\'') k4^=1;
if(tmp[k] == '"') k5^=1;
if(k1 > 0 || k2 > 0 || k3 > 0) break;
}
pb = k + 1;
k1 = k2 = k3 = k4 = k5 = 0;
REP(k,pl,tmp.size()){
if(k4==0 && k5==0){
if(tmp[k] == '(') k1++;
if(tmp[k] == ')') k1--;
if(tmp[k] == '[') k2++;
if(tmp[k] == ']') k2--;
if(tmp[k] == '{') k3++;
if(tmp[k] == '}') k3--;
}
if(tmp[k] == '\'') k4^=1;
if(tmp[k] == '"') k5^=1;
if(k1 < 0 || k2 < 0 || k3 < 0) break;
}
pa = k;
bg = tmp.substr(pb, pl-pb);
ed = tmp.substr(pl+dots.size(), pa-pl-dots.size());
if(fg==0){
fg = 1;
fbg = bg;
fed = ed;
}
if(bg==fbg) tmp = tmp.substr(0, pb) + vn + tmp.substr(pa);
else tmp = tmp.substr(0, pb) + vn + " - (" + fbg + ") + (" + bg + ")" + tmp.substr(pa);
}
stc += "rep(" + vn + ", " + fbg + ", (" + fed + ") + 1) ";
stc += tmp;
stc += "}";
insert(stc, str.size());
return "";
}
string sentence_gcdlcm_sub(vector<string> vs, string op){
while(vs.size() > 1){
if(op=="+" || op=="*"){
vs[0] = "(" + vs[0] + ")" + op + "(" + vs[1] +")";
} else {
vs[0] = op + "(" + vs[0] + ", " + vs[1] + ")";
}
vs.erase(vs.begin()+1);
}
return vs[0];
}
string sentence_gcdlcm(string tmp, int blocked = 1){
int i, j, k;
string stc, func;
string vn, loop_vn, vtype;
vector<string> vs, arr, barr, varr, tmpvs, vsub;
for(;;){
vs.clear();
if(vs.size()==0 && g_flags.count("no-gcd()")==0){
vs = findFunction(tmp,"gcd()");
if(vs.size()==3) func = "GCD_L", ifun.doit.insert((string)"gcd");
}
if(vs.size()==0 && g_flags.count("no-GCD()")==0){
vs = findFunction(tmp,"GCD()");
if(vs.size()==3) func = "GCD_L", ifun.doit.insert((string)"gcd");
}
if(vs.size()==0 && g_flags.count("no-lcm()")==0){
vs = findFunction(tmp,"lcm()");
if(vs.size()==3) func = "LCM_L", ifun.doit.insert((string)"lcm");
}
if(vs.size()==0 && g_flags.count("no-LCM()")==0){
vs = findFunction(tmp,"LCM()");
if(vs.size()==3) func = "LCM_L", ifun.doit.insert((string)"lcm");
}
if(vs.size()==0 && g_flags.count("no-min()")==0){
vs = findFunction(tmp,"min()");
if(vs.size()==3 && vs[1].size()==0) vs.clear();
if(vs.size()==3) func = "min_L", ifun.doit.insert((string)"min_L");
}
if(vs.size()==0 && g_flags.count("no-MIN()")==0){
vs = findFunction(tmp,"MIN()");
if(vs.size()==3) func = "min_L", ifun.doit.insert((string)"min_L");
}
if(vs.size()==0 && g_flags.count("no-max()")==0){
vs = findFunction(tmp,"max()");
if(vs.size()==3 && vs[1].size()==0) vs.clear();
if(vs.size()==3) func = "max_L", ifun.doit.insert((string)"max_L");
}
if(vs.size()==0 && g_flags.count("no-MAX()")==0){
vs = findFunction(tmp,"MAX()");
if(vs.size()==3) func = "max_L", ifun.doit.insert((string)"max_L");
}
if(vs.size()==0 && g_flags.count("no-sum()")==0){
vs = findFunction(tmp,"sum()");
if(vs.size()==3) func = "+";
}
if(vs.size()==0 && g_flags.count("no-SUM()")==0){
vs = findFunction(tmp,"SUM()");
if(vs.size()==3) func = "+";
}
if(vs.size()==0 && g_flags.count("no-mul()")==0){
vs = findFunction(tmp,"mul()");
if(vs.size()==3) func = "*";
}
if(vs.size()==0 && g_flags.count("no-MUL()")==0){
vs = findFunction(tmp,"MUL()");
if(vs.size()==3) func = "*";
}
if(vs.size()==0) break;
stc = "";
loop_vn = getUnusedVarName();
arr = split_p(vs[1], ',');
rep(k,arr.size()){
trim(arr[k]);
barr = rd_wt_array(arr[k]);
if(barr.size()==4){
vn = getUnusedVarName();
vtype = getEquationType(barr[1]);
stc += vtype + " " + vn + ";";
if(barr[1][0]=='('){
barr[1] = barr[1].substr(1, barr[1].size()-2);
varr = split_p(barr[1], ',');
} else {
varr.clear();
varr.push_back(barr[1]);
}
stc += "if(" + barr[2] + "==0){";
if(func=="*" || func=="LCM_L"){
stc += vn + " = 1;";
} else {
stc += vn + " = 0;";
}
stc += "} else {";
vsub.clear();
rep(i,varr.size()) vsub.push_back(varr[i] + "[0]");
stc += vn + " = " + sentence_gcdlcm_sub(vsub,func) + ";";
stc += "rep(" + loop_vn + ", 1, " + barr[2] + "){";
vsub.clear();
rep(i,varr.size()) vsub.push_back(varr[i] + "[" + loop_vn + "]");
if(func=="+" || func=="*"){
stc += vn + " " + func + "= " + sentence_gcdlcm_sub(vsub,func) + ";";
} else {
stc += vn + " = " + func + "(" + vn + ", " + sentence_gcdlcm_sub(vsub,func) + ");";
}
stc += "}";
stc += "}";
arr[k] = vn;
}
}
if(stc != ""){
stc = "int " + loop_vn + ";" + stc;
tmp = sentence_gcdlcm_sub(arr, func);
if(blocked){
stc = "{" + stc;
stc += vs[0] + tmp + vs[2];
stc += "}";
insert(stc, str.size());
return "";
} else {
insert(stc, str.size());
tmp = vs[0] + tmp + vs[2];
}
} else {
tmp = sentence_gcdlcm_sub(arr, func);
tmp = vs[0] + tmp + vs[2];
}
}
return tmp;
}
string sentence_otherfunctions(string tmp){
vector<string> vs, vtmp;
for(;;){
vs = findFunction(tmp, "walloc1d()");
if(vs.size() == 3) ifun.doit.insert((string)"walloc1d");
vs = findFunction(tmp, "walloc2d()");
if(vs.size() == 3) ifun.doit.insert((string)"walloc2d");
vs = findFunction(tmp, "malloc1d()");
if(vs.size() == 3) ifun.doit.insert((string)"malloc1d");
vs = findFunction(tmp, "malloc2d()");
if(vs.size() == 3) ifun.doit.insert((string)"malloc2d");
vs = findFunction(tmp, "free1d()");
if(vs.size() == 3) ifun.doit.insert((string)"free1d");
vs = findFunction(tmp, "free2d()");
if(vs.size() == 3) ifun.doit.insert((string)"free2d");
vs = findFunction(tmp, "sortA()");
if(vs.size() == 3){
vtmp = split_p(vs[1], ',');
if(vtmp.size()==3) ifun.doit.insert((string)"sortA_2");
if(vtmp.size()==4) ifun.doit.insert((string)"sortA_3");
if(vtmp.size()==5) ifun.doit.insert((string)"sortA_4");
tmp = vs[0] + "sortA_L(" + vs[1] + ")" + vs[2];
continue;
}
vs = findFunction(tmp, "Unique()");
if(vs.size() == 3){
vtmp = split_p(vs[1], ',');
if(vtmp.size()==2 || vtmp.size()==3) ifun.doit.insert((string)"Unique1");
if(vtmp.size()==3 || vtmp.size()==4) ifun.doit.insert((string)"Unique2");
tmp = vs[0] + "Unique_L(" + vs[1] + ")" + vs[2];
continue;
}
vs = findFunction(tmp, "fib_mod()");
if(vs.size()!=3) vs = findFunction(tmp, "fibonacci_mod()");
if(vs.size() == 3){
vtmp = split_p(vs[1], ',');
if(vtmp.size()==1){
vs[1] = vs[1] + ", MD";
ifun.doit.insert((string)"define_MD");
}
ifun.doit.insert((string)"fibonacci_mod");
tmp = vs[0] + "fibonacci_mod_L(" + vs[1] + ")" + vs[2];
continue;
}
vs = findFunction(tmp, "coordcomp()");
if(vs.size() != 3) vs = findFunction(tmp, "coord_comp()");
if(vs.size() == 3){
vtmp = split_p(vs[1], ',');
if(vtmp.size() <= 4) ifun.doit.insert((string)"coordcomp_1");
if(vtmp.size() >= 4) ifun.doit.insert((string)"coordcomp_2");
tmp = vs[0] + "coordcomp_L(" + vs[1] + ")" + vs[2];
continue;
}
vs = findFunction(tmp, "runLength()");
if(vs.size() == 3) ifun.doit.insert((string)"runLength");
vs = findFunction(tmp, "reduceFraction()");
if(vs.size() == 3) ifun.doit.insert((string)"reduceFraction");
break;
}
return tmp;
}
int isOperator(char c){
if(c=='+' || c=='-' || c=='*' || c=='/' || c=='%'|| c=='=') return 1;
if(c=='&' || c=='|' || c=='^' || c=='~') return 1;
return 0;
}
void sentence_main(string tmpstr, string tmp, int tt, int &fg_return){
pair<string, char> stchar;
vector<string> vtmp;
code_replace(tmp);
// fprintf(stderr, "sentence main [%s] [%s]\n", tmpstr.c_str(), tmp.c_str());
stchar = nextToken(tmp);
if(stchar.first == "return") fg_return = 1; else fg_return = 0;
tmp = sentence_dot_loop(tmp); // A[0..N-1] = 0;
if(tmp=="") return;
tmp = sentence_hatena_minmax_operator(tmp); // >?=, <?=
if(tmp=="") return;
tmp = sentence_times_operator(tmp); // *の省略
if(tmp=="") return;
tmp = sentence_inequation(tmp); // &&の省略
if(tmp=="") return;
tmp = sentence_pow_operator(tmp); // **
if(tmp=="") return;
tmp = sentence_div_operator(tmp); // /+
if(tmp=="") return;
tmp = sentence_minmax_function(tmp); // min[](), max[](), argmin[](), argmax[]()
if(tmp=="") return;
tmp = sentence_gcdlcm(tmp); // gcd(), lcm(), min(), max
if(tmp=="") return;
tmp = sentence_otherfunctions(tmp); // runLength(), reduceFraction()
if(tmp=="") return;
tmp = sentence_reader(tmp); // rd()
if(tmp=="") return;
tmp = sentence_writer(tmp); // wt(), wtLn(), wtSp(), wtN()
if(tmp=="") return;
str.push_back(tmpstr + tmp);
nxt.push_back(-1);
if(tt==-1){
strtype.push_back((string)"sentence");
} else {
strtype.push_back((string)"sentence-var-def");
}
}
string equation_main(string tmp){
tmp = sentence_times_operator(tmp);
tmp = sentence_inequation(tmp);
tmp = sentence_pow_operator(tmp);
tmp = sentence_div_operator(tmp);
tmp = sentence_gcdlcm(tmp, 0);
tmp = sentence_minmax_function(tmp, 0);
return tmp;
}
void set(string &in, string tp){
int i, st, cnt, tt, fg;
int k1, k2, k3, k4, k5;
int end_type = 0;
int fg_main = 0, fg_return = 0;
string tmp, tmpstr;
string str_type, str_var;
vector<string> str_arg;
pair<string, char> stchar;
vector<string> vtmp;
type = tp;
set_init();
ftrim(in);
if(tp != "program" && in[0]=='{') end_type = 1, in = in.substr(1);
if(tp == "program") end_type = 2;
for(;;){
ftrim(in);
tmp_vartype.clear();
// printf("--- %s\n",in.substr(0,10).c_str());
if(in.substr(0,12) == "//no-insert-"){
for(i=12;;i++) if(isspace(in[i]) || in[i]=='\0') break;
g_flags.insert(in.substr(2,i-2));
in = in.substr(i);
}
if(in.substr(0,13) == "//no-unlocked" && (isspace(in[13]) || in[13]=='\0')){
g_flags.insert((string)"no-unlocked");
in = in.substr(13);
continue;
}
if(in.substr(0,10) == "//no-gcd()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-gcd()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-GCD()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-GCD()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-lcm()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-lcm()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-LCM()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-LCM()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-min()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-min()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-MIN()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-MIN()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-max()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-max()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-MAX()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-MAX()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-sum()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-sum()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-SUM()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-SUM()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-mul()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-mul()");
in = in.substr(10);
continue;
}
if(in.substr(0,10) == "//no-MUL()" && (isspace(in[10]) || in[10]=='\0')){
g_flags.insert((string)"no-MUL()");
in = in.substr(10);
continue;
}
if(in.substr(0,2) == "//"){
rep(i,in.size()) if(in[i] == '\n'){ i++; break; }
in = in.substr(i);
continue;
}
if(in.substr(0,2) == "/*"){
REP(i,1,in.size()) if(in.substr(i-1,2) == "*/"){ i++; break; }
in = in.substr(i);
continue;
}
if(end_type==-1) break;
if(end_type==0) end_type = -1;
if(in.size()==0 && end_type==2) break;
if(in.size() && in[0]=='}' && end_type==1){
in = in.substr(1);
if(name == "int main()" && fg_return == 0){
str.push_back((string)"return 0;");
nxt.push_back(-1);
strtype.push_back((string)"sentence");
}
break;
}
if(in.substr(0,8) == "#include"){
cnt = 0;
for(i=0;;i++){
if(in[i]=='"') cnt++;
if(cnt==2 || in[i]=='>'){ i++; break; }
}
tmp = in.substr(0, i);
in = in.substr(i);
str.push_back(tmp);
nxt.push_back(-1);
strtype.push_back((string)"sentence-include");
continue;
}
if(in.substr(0,7) == "#define"){
string in_tmp = in.substr(7);
stchar = nextToken(in_tmp);
if(stchar.first == "MD") ifun.already.insert((string)"define_MD");
if(stchar.first == "PI") ifun.already.insert((string)"define_PI");
for(i=0;;i++){
if(in[i]=='\n' || in[i]=='\r') break;
}
tmp = in.substr(0, i);
in = in.substr(i);
str.push_back(tmp);
nxt.push_back(-1);
strtype.push_back((string)"sentence-define");
continue;
}
stchar = nextToken(in);
if(stchar.second == ':'){
for(i=0;;i++) if(in[i]==':'){ i++; break; }
if(in[i]!=':'){
tmp = in.substr(0, i);
in = in.substr(i);
str.push_back(tmp);
nxt.push_back(-1);
strtype.push_back((string)"sentence-label");
continue;
}
}
if(stchar.first == "case" || stchar.first == "default"){
for(i=0;;i++) if(in[i]==':'){ i++; break; }
tmp = in.substr(0, i);
in = in.substr(i);
str.push_back(tmp);
nxt.push_back(-1);
strtype.push_back((string)"sentence-case-label");
continue;
}
tmpstr = "";
for(;;){
stchar = nextToken(in);
// printf("[%s] [%c]\n",stchar.first.c_str(),stchar.second);
if(stchar.first == "template"){
cnt = 0;
for(i=0;;i++){
if(in[i]=='<') cnt++;
if(in[i]=='>') cnt--;
if(cnt==0 && in[i]=='>'){ i++; break; }
}
tmpstr += in.substr(0, i) + " ";
in = in.substr(i);
ftrim(in);
continue;
}
if(stchar.first == "inline"){
tmpstr += "inline ";
in = in.substr(6);
ftrim(in);
continue;
}
break;
}
if(tmpstr.size()){
string tt = tmpstr;
// fprintf(stderr, "%s\n", tt.c_str());
trim_until(tt, '<', '>');
if(tt.size() >= 2){
tt = tt.substr(1, tt.size()-2);
vtmp = split_p(tt, ',');
rep(i,vtmp.size()){
trim(vtmp[i]);
if(vtmp[i].substr(0,6)=="class "){
vtmp[i] = vtmp[i].substr(5);
trim(vtmp[i]);
tmp_vartype.insert(vtmp[i]);
}
}
}
}
fg = 0;
tt = -1;
REP(i,1,100) if(isValidVarType(in.substr(0,i), in[i])) tt = i;
stchar = nextToken(in);
if(tt >= 0){
for(i=0;;i++){
if(in[i] == '='){
string tmp = in.substr(0,i);
if(strpos_ns_t(tmp, "operator") == -1) break;
}
if(in[i] == ';') break;
if(in[i] == '('){ fg++; stchar.first = "function"; break; }
}
}
if(stchar.first == "if" && stchar.second =='(') fg = 1;
if(stchar.first == "for" && stchar.second =='(') fg = 1;
if(stchar.first == "rep" && stchar.second =='(') fg = 1;
if(stchar.first == "REP" && stchar.second =='(') fg = 1;
if(stchar.first == "while" && stchar.second =='(') fg = 1;
if(stchar.first == "switch" && stchar.second =='(') fg = 1;
if(stchar.first == "do") fg = 2;
if(stchar.first == "struct") fg = 3;
if(stchar.first == "else") fg = 4;
if(fg==2){
string str_t = in.substr(4,100);
pair<string,char> stch_t = nextToken(str_t);
if(stch_t.first == "if" && stch_t.second == '('){
fg = 1;
stchar.first = "else if";
}
}
if(fg || in[0]=='{'){
fg_return = 0;
if(fg==1){
cnt = 0;
rep(i,in.size()){
if(in[i] == '(') cnt++;
if(in[i] == ')') cnt--;
if(in[i] == ')' && cnt == 0){
i++; break;
}
}
} else if(fg==2 || fg==4) {
i = stchar.first.size();
} else if(fg==3) {
rep(i,in.size()) if(in[i]=='{' || in[i] == ';') break;
tmp = in.substr(0, i);
trim(tmp);
vtmp = split_p(tmp, ' ');
if(tmpstr.size() == 0) add_vartype(vtmp[vtmp.size()-1]);
else add_tvartype(vtmp[vtmp.size()-1]);
} else {
i = 0;
}
tmp = in.substr(0, i);
in = in.substr(i);
// printf("[[ %s : %s : fg = %d]]\n", tmp.c_str(), in.substr(0,10).c_str(), fg);
// exit(0);
code_replace(tmp);
tmp = equation_main(tmp);
if(type=="program" && tmp=="" && fg_main==0) tmp = "int main()", fg_main = 1;
if(tmp.substr(0,3) == "rep" || tmp.substr(0,3) == "REP"){
while(tmp[0]!='(') tmp = tmp.substr(1);
while(tmp[tmp.size()-1]!=')') tmp = tmp.substr(0, tmp.size()-1);
tmp = tmp.substr(1, tmp.size()-2);
str_arg = split_p(tmp, ',');
rep(i,str_arg.size()) trim(str_arg[i]);
if(str_arg.size()==1){
str_arg.push_back(str_arg[0]);
str_arg[0] = getUnusedVarName();
}
if(localvar.count(str_arg[0])==0 && argvar.count(str_arg[0])==0 && globalvar.count(str_arg[0])==0){
string vardef;
pair<string,string> vardefs;
vardef = "int " + str_arg[0] + ";";
vardefs = var_definition(vardef);
add_localvar(vardefs.first, vardefs.second);
}
if(str_arg.size()==2){
tmp = (string)"for(" + str_arg[0] + "=0;" + str_arg[0] + "<" + str_arg[1] + ";" + str_arg[0] + "++)";
} else if(str_arg.size()==3){
tmp = (string)"for(" + str_arg[0] + "=" + str_arg[1] + ";" + str_arg[0] + "<" + str_arg[2] + ";" + str_arg[0] + "++)";
} else {
assert(0);
}
stchar.first = "for";
}
code *cc = new code;
cc->setUpnode(this);
if(tmpstr.size()){
string tt = tmpstr;
trim_until(tt, '<', '>');
// assert(tt.size()>=2);
if(tt.size() >= 2){
tt = tt.substr(1, tt.size()-2);
vtmp = split_p(tt, ',');
rep(i,vtmp.size()){
trim(vtmp[i]);
if(vtmp[i].substr(0,6)=="class "){
vtmp[i] = vtmp[i].substr(5);
trim(vtmp[i]);
cc->vartype.insert(vtmp[i]);
}
}
}
}
if(stchar.first == "function"){
string tt = tmp;
pair<string,string> ss;
trim_until(tt, '(', ')');
assert(tt.size()>=2);
tt = tt.substr(1, tt.size()-2);
vtmp = split_p(tt, ',');
rep(i,vtmp.size()){
trim(vtmp[i]);
if(vtmp[i].size()==0 || vtmp[i]=="void") continue;
ss = cc->var_definition(vtmp[i]);
cc->argvar[ss.first] = ss.second;
}
}
if(stchar.first == "for"){
}
cc->name = tmpstr + tmp;
cc->set(in, (string)"block");
nxt.push_back(nxtlst.size());
nxtlst.push_back(cc);
str.push_back(tmpstr + tmp);
strtype.push_back((string)"block-"+stchar.first);
continue;
}
k1 = k2 = k3 = k4 = k5 = 0;
st = 0;
if(tt != -1) st = tt;
for(i=st;;i++){
int is_not_vardef = 0;
if(k4==0 && k5==0){
if(in[i] == '(') k1++;
if(in[i] == ')') k1--;
if(in[i] == '[') k2++;
if(in[i] == ']') k2--;
if(in[i] == '{') k3++;
if(in[i] == '}') k3--;
}
if(in[i] == '\'') k4^=1;
if(in[i] == '"') k5^=1;
if(k1==0 && k2==0 && k3==0 && k4==0 && k5==0){
if(in[i] == ',' || in[i] == ';'){
tmp = in.substr(st, i+1-st);
if(tt>=0) tmp[tmp.size()-1] = ';';
if(tt >= 0){
int before_count = insert_count;
if(isalnum(tmp[0]) || tmp[0]=='_') tmp = " "+tmp;
str_type = in.substr(0, tt);
tmp = str_type + tmp;
code_replace(tmp);
pair<string,string> pss = var_definition(tmp);
str_var = pss.first;
str_type = pss.second;
if(insert_count != before_count){
vector<string> vvs = split_p(str_type, ',');
tmp = str_var + " = " + vvs[3] + ";";
vvs[3] = "";
str_type = vvs[0] + "," + vvs[1] + "," + vvs[2] + "," + vvs[3];
is_not_vardef = 1;
}
add_localvar(str_var, str_type);
}
sentence_main(tmpstr, tmp, is_not_vardef?-1:tt, fg_return);
if(in[i] == ','){
st = i+1;
continue;
} else {
i++;
break;
}
}
}
}
in = in.substr(i);
continue;
}
}
void debug_writer(int tab = 0){
int i, j;
std::set<string>::iterator it1;
map<string,string>::iterator it2;
printf("vartype :");
for(it1=vartype.begin();it1!=vartype.end();it1++) printf(" (%s)", it1->c_str()); puts("");
printf("tvartype :");
for(it1=tvartype.begin();it1!=tvartype.end();it1++) printf(" (%s)", it1->c_str()); puts("");
printf("localvar :");
for(it2=localvar.begin();it2!=localvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts("");
printf("globalvar:");
for(it2=globalvar.begin();it2!=globalvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts("");
printf("argvar :");
for(it2=argvar.begin();it2!=argvar.end();it2++) printf(" (%s->%s)", it2->first.c_str(), it2->second.c_str()); puts("");
rep(i,str.size()){
rep(j,tab) printf(" ");
printf("%4d: %s [%s]\n",i,str[i].c_str(),strtype[i].c_str());
if(nxt[i]>=0) nxtlst[nxt[i]]->debug_writer(tab+4);
}
}
void output_vardef(int mode, int tab){
int i, f;
std::set<string> tp;
std::set<string>::iterator it;
vector<string> tmp;
map<string,string>::iterator mt;
for(mt=localvar.begin(); mt!=localvar.end(); mt++){
tmp = split_p2(mt->second, ',');
assert(tmp.size()==4);
if(tmp[0].substr(0,10) == "inplace_L ") continue;
tp.insert(tmp[0]);
}
for(it=tp.begin(); it!=tp.end(); it++){
rep(i,tab) printf(" ");
f = 0;
for(mt=localvar.begin(); mt!=localvar.end(); mt++){
tmp = split_p2(mt->second, ',');
assert(tmp.size()==4);
if(*it == tmp[0]){
if(f) printf(", ");
else printf("%s ", it->c_str());
f++;
printf("%s%s%s", tmp[1].c_str(), mt->first.c_str(), tmp[2].c_str());
if(tmp[3].size() != 0) printf("=%s",tmp[3].c_str());
}
}
printf(";\n");
}
}
void output(int mode, int tab = 0){
int i, j;
int var = 0;
string s;
rep(i,str.size()+1){
if(i==str.size()){
if(var==0) output_vardef(mode, tab);
var = 1;
break;
}
if(strtype[i]=="sentence-var-def"){
if(str[i].substr(0,10) != "inplace_L ") continue;
str[i] = str[i].substr(10);
}
if(var==0 && (type != "program" || strtype[i] != "block-inserted" || i==str.size()-1)){
var = 1;
output_vardef(mode, tab);
}
if(strtype[i]=="block-inserted"){
nxtlst[nxt[i]]->output(mode, tab);
continue;
}
rep(j,tab) printf(" ");
s = str[i];
if(g_flags.count((string)"no-unlocked")) replaceAll_ns_t(s, "putchar_unlocked", "putchar");
if(g_flags.count((string)"no-unlocked")) replaceAll_ns_t(s, "getchar_unlocked", "getchar");
printf("%s",s.c_str());
if(strtype[i]=="block-while"){
if(nxtlst[nxt[i]]->is_empty_block()){
printf(";\n");
continue;
}
}
if(strtype[i].substr(0,5)=="block"){
printf("{\n");
} else {
printf("\n");
}
if(nxt[i]>=0) nxtlst[nxt[i]]->output(mode, tab+(mode==0?2:0));
if(strtype[i].substr(0,5)=="block"){
rep(j,tab) printf(" ");
printf("}\n");
}
}
}
};
int main(int argc, char **argv){
int i, k, f;
char buf[10001];
string str, str_store;
if(argc >= 2) str = argv[1];
if(str == "-lib"){
str = "";
for(;;){
k = fread(buf, 1, 10000, stdin);
buf[k] = '\0';
str += buf;
if(k < 10000) break;
}
putchar('"');
rep(i,str.size()){
if(str.substr(i,6)=="-----\n"){
putchar('"');
putchar('\n');
putchar('"');
i += 5;
continue;
}
if(str.substr(i,7)=="-----\r\n"){
putchar('"');
putchar('\n');
putchar('"');
i += 6;
continue;
}
if(str[i]=='"'){
putchar('\\');
putchar('"');
} else if(str[i]=='\\'){
putchar('\\');
putchar('\\');
} else if(str[i]=='\n'){
putchar('\\');
putchar('n');
} else if(str[i]=='\r'){
} else {
putchar(str[i]);
}
}
putchar('"');
return 0;
}
if(str == "-libshow"){
int i;
ifun.set();
rep(i,ifun.name.size()){
puts("-------------------------------");
printf("%s\n------\n", ifun.name[i].c_str());
printf("%s\n\n\n", ifun.func[ifun.name[i]].c_str());
}
return 0;
}
for(;;){
k = fread(buf, 1, 10000, stdin);
buf[k] = '\0';
str += buf;
if(k < 10000) break;
}
str_store = str;
ifun.set();
string tmp;
code c;
c.up = NULL;
c.set(str, (string)"program");
tmp = ifun.get_insert_string((string)"first");
c.insert(tmp, 0);
tmp = ifun.get_insert_string((string)"main_first");
rep(i,c.str.size()){
if(c.str[i].substr(0,9) == "int main(" || c.str[i].substr(0,10) == "void main("){
c.nxtlst[c.nxt[i]]->insert(tmp,0);
}
}
// c.debug_writer(); return 0;
c.output(0);
printf("// cLay varsion 20170910-1\n");
str = str_store;
f = 0;
printf("\n// --- original code ---\n");
rep(i,str.size()){
if(!f) printf("// "), f = 1;
if(str[i]=='\r') continue;
putchar(str[i]);
if(str[i]=='\n') f = 0;
}
return 0;
}
Current time: 2024年03月29日01時28分25秒
Last modified: 2017年09月10日21時17分13秒 (by laycrs)
Tags: no_tags
トップページに戻る
Logged in as: unknown user (not login)