Problem:
Problem C: Factorization
Problem
ukuku1333さんはおっちょこちょいなので、
x
の一次式の積を展開したら、元の一次式がわからなくなってしまった。
x
の
n
次多項式が与えられるので、因数分解して元のxの一次式の積の形にせよ。
x
の
n
次多項式は以下のBNFによって与えられる。
<多項式> := <項> | <多項式>+<項> | <多項式>−<項> 
<項> := x^<指数> | <係数>x^<指数> | <係数>x | <定数> 
<指数> := [2-5] 
<係数> := [1-9][0-9]* 
<定数> := [1-9][0-9]*
指数及び係数が省略されている場合は1とみなす。
Input
入力は以下の形式で与えられる。
S
x
の
n
次多項式を表す文字列
S
が一行に与えられる。
Constraints
入力は以下の条件を満たす。
2 ≤
n
≤ 5
与えられる式の項の数を
m
とすると、1 ≤
i
<
j
≤
m
なる任意の
i
,
j
の組に対して、
i
番目の項の次数は
j
番目の項の次数より大きいことが保証される
与えられる
x
の
n
次多項式は、
x
の一次式の積の形に因数分解したもので表すことができることが保証される
係数、定数の絶対値はそれぞれ2×10
3
以下である
次数が最大のものの係数は1であり、省略されていることが保証される
展開する前のそれぞれの一次式の元の定数項は0ではない整数であることが保証される
展開する前のそれぞれの一次式の元の定数項は相異なることが保証される
Output
S
を
x
の一次式の積の形に因数分解したものを、定数項の小さいものから順に出力せよ。
出力の最後には改行を入れること。
Sample Input 1
x^2+3x+2
Sample Output 1
(x+1)(x+2)
Sample Input 2
x^2-1
Sample Output 2
(x-1)(x+1)
Sample Input 3
x^5+15x^4+85x^3+225x^2+274x+120
Sample Output 3
(x+1)(x+2)(x+3)(x+4)(x+5)
Sample Input 4
x^3-81x^2-1882x-1800
Sample Output 4
(x-100)(x+1)(x+18)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

struct Poly {
    int n = 0;

    std::vector<int> coef;

    Poly() {}
    Poly(int n): n(n), coef(n + 1) {}
    Poly(const std::vector<int>& constants) {
        int m = constants.size();
        resize(m);
        for (int s = 0; s < (1 << m); s++) {
            int c = 1;
            int d = 0;
            for (int i = 0; i < m; i++) {
                if (s & (1 << i)) {
                    c *= constants[i];
                } else {
                    d++;
                }
            }
            coef[d] += c;
        }
    }

    void resize(int n_) {
        if (n_ < n) return;
        n = n_;
        coef.resize(n_ + 1);
    }

    void set_coef(int i, int v) {
        coef.at(i) = v;
    }

    int get_coef(int i) {
        return coef.at(i);
    }

    friend Poly operator+(Poly lhs, Poly rhs) {
        int n = std::max(lhs.n, rhs.n);
        lhs.resize(n);
        rhs.resize(n);
        Poly res(n);
        for (int i = 0; i <= n; i++) {
            res.set_coef(i, lhs.get_coef(i) + rhs.get_coef(i));
        }
        return res;
    }

    friend Poly operator-(Poly lhs, Poly rhs) {
        int n = std::max(lhs.n, rhs.n);
        lhs.resize(n);
        rhs.resize(n);
        Poly res(n);
        for (int i = 0; i <= n; i++) {
            res.set_coef(i, lhs.get_coef(i) - rhs.get_coef(i));
        }
        return res;
    }

    friend bool operator==(Poly lhs, Poly rhs) {
        if (lhs.n != rhs.n) return false;
        for (int i = 0; i <= lhs.n; i++) {
            if (lhs.coef[i] != rhs.coef[i]) return false;
        }
        return true;
    }
};

struct Factor {
    int constant;
    int coef;

    Factor() {}
    Factor(int constant, int coef = 1): constant(constant), coef(coef) {}
};

bool operator<(Factor lhs, Factor rhs) {
    return lhs.constant < rhs.constant;
}

std::vector<int> factorize(int n) {
    std::vector<int> res;
    n = std::abs(n);
    for (int i = 2; i * i <= n; i++) {
        while (n % i == 0) {
            n /= i;
            res.push_back(i);
        }
    }
    if (n != 1) {
        res.push_back(n);
    }
    return res;
}

std::vector<Factor> factorize(Poly poly) {
    int n = poly.n;
    auto factor = factorize(poly.get_coef(0));

    std::vector<int> constants(n, 1);

    auto ok = [&]() {
        for (int s = 0; s < (1 << n); s++) {
            for (int i = 0; i < n; i++) {
                if (s & (1 << i)) {
                    constants[i] = -constants[i];
                }
            }
            Poly res(constants);
            if (res == poly) {
                return true;
            }
            for (int i = 0; i < n; i++) {
                if (s & (1 << i)) {
                    constants[i] = -constants[i];
                }
            }
        }
        return false;
    };

    auto dfs = [&](auto self, int i) -> bool {
        if (i == (int)factor.size()) {
            if (ok()) {
                return true;
            }
            return false;
        }

        for (int j = 0; j < n; j++) {
            if (poly.get_coef(j) == 0) continue;
            constants[j] *= factor[i];
            if (self(self, i + 1)) return true;
            constants[j] /= factor[i];
        }
        return false;
    };
    dfs(dfs, 0);

    std::vector<Factor> res(n);
    for (int i = 0; i < n; i++) {
        res[i] = Factor(constants[i]);
    }
    return res;
}

std::string to_string(Factor factor) {
    std::string res;
    res.push_back('(');
    if (factor.coef != 1) res += std::to_string(factor.coef);
    res.push_back('x');
    if (factor.constant > 0) res.push_back('+');
    res += std::to_string(factor.constant);
    res.push_back(')');
    return res;
}

struct Parser {
    using CopyIter = std::string::const_iterator;
    using Iter = CopyIter&;
    std::string line;
    Parser(std::string line): line(line) {}

    Poly parse() {
        auto it = line.cbegin();
        return poly(it);
    }

    void skip(Iter it, char c) {
        ++it;
    }

    Poly poly(Iter it) {
        auto res = term(it);
        while (it != line.end() && (*it == '+' || *it == '-')) {
            if (*it == '+') {
                skip(it, '+');
                res = res + term(it);
            } else {
                skip(it, '-');
                res = res - term(it);
            }
        }
        return res;
    }

    Poly term(Iter it) {
        Poly res;
        int v = coef(it);
        int e = 0;
        if (it != line.end() && *it == 'x') {
            skip(it, 'x');
            if (it != line.end() && *it == '^') {
                skip(it, '^');
            }
            e = exp(it);
        }

        res.resize(e);
        res.set_coef(e, v);

        return res;
    }

    int coef(Iter it) {
        int res = number(it);
        if (res == 0) res = 1;
        return res;
    }

    int exp(Iter it) {
        int res = number(it);
        if (res == 0) res = 1;
        return res;
    }

    int number(Iter it) {
        int res = 0;
        while (it != line.end() && std::isdigit(*it)) {
            res = 10 * res + *it - '0';
            it++;
        }

        return res;
    }
};

int main() {
    std::string line;
    std::getline(std::cin, line);

    Parser parser(line);
    auto poly = parser.parse();

    auto factors = factorize(poly);
    std::sort(factors.begin(), factors.end());
    for (auto factor: factors) {
        std::cout << to_string(factor);
    }
    std::cout << std::endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3504
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define ll long long
#define ld long double
#define print(t) cout << t << endl 
#define all(a)  (a).begin(),(a).end()
// << std::fixed << std::setprecision(0)
const ll INF = 1LL << 60;
 
template<class T> bool chmin(T& a, T b){
 if(a > b){
  a = b;
  return true;
 }
  return false;
}
 
template<class T> bool chmax(T& a, T b){
 if(a < b){
  a = b;
  return true;
 }
  return false;
}
  
ll lpow(ll x,ll n){
  ll ans = 1;
  while(n >0){
    if(n & 1)ans *= x;
    x *= x;
    n >>= 1;
  }
  return ans;
}

typedef string::const_iterator State;

class ParseError {};
//プロトタイプ宣言
void expression(State &begin);
void term(State &begin,bool plus);
void number(State &begin,bool plus);
void x(State &begin);
void consume(State &begin, char expected);

vector<ll> parsed;
vector<ll> ans;

void expression(State &begin){
  for(;;){
    if(*begin == 'x'){
      x(begin);
    }else if(*begin == '+'){
      term(begin,true);
    }else if(*begin == '-'){
      term(begin,false);
    }else{
      break;
    }
  }
}

void term(State &begin,bool plus){
  if(plus){
    consume(begin,'+');
  }else{
    consume(begin,'-');
  }
  number(begin,plus);
  if(*begin == 'x'){
    x(begin);
  }

}

void number(State & begin,bool plus){
    ll ret = 0;
  while(isdigit(*begin)){
    ret *= 10;
    ret += *begin - '0';
    begin++;
  }
if(ret == 0){
    ret =1;
  }
  if(plus == false){
    ret *= -1;
  }
  //先読みをする
  ll id;
  if(*begin == '='){
    id = (ll)parsed.size()-1;
  }else{
    consume(begin,'x');
    if(*begin == '^'){
      begin++;
      ll p = (ll)(*begin - '0');
      id = (ll)parsed.size() - (p+1);
      begin--;
    }else{
      id = (ll)parsed.size()-2;
    }
    begin--;
  }
  parsed[id] = ret;
}

ll last = -1;
void x(State &begin){
  consume(begin,'x');
  if(*begin == '^'){
    consume(begin,'^');
    if(isdigit(*begin)){
      if(last == -1){
        last = *begin - '0';
        begin++;
        parsed.resize(last+1);
        parsed[0] = 1;
      }
      else {
        begin++;
        last--;
      }
    }
  }else{
    //x^3-x-1とかもゆるされるので
    // if(last != 2){
    //   cerr << "Expected '" << last -1 << "' but got '" << *begin << "'" << endl;
    //   cerr << "Rest string is '";
    //   while(*begin){
    //     cerr << *begin++;
    //   }
    //   cerr << "'" << endl;
    //   throw ParseError();
    // }
  }
}

void consume(State &begin, char expected){
  if(*begin == expected){
    begin++;
  }else{
    cerr << "Expected '" << expected << "' but got '" << *begin << "'" << endl;
    cerr << "Rest string is '";
    while(*begin){
      cerr << *begin++;
    }
    cerr << "'" << endl;
    throw ParseError();
  }
}

vector<ll> divisor(ll n){
  vector<ll> ret;
  for(ll i = 1;i * i <= n;i++){
    if(n % i == 0){
      ret.push_back(i);
      if(i * i != n)ret.push_back(n/i);
    }
  }
  //昇順
  sort(all(ret));
  return ret;
}

set<vector<ll>> se;
bool check(vector<ll> ch){
  sort(all(ch));
  if(se.count(ch))return false;
  vector<ll> now_ans((ll)parsed.size(),0);
  rep(i,1LL << ch.size()){
    ll pro = 1;
    ll bit_cnt = 0;
    rep(j,(ll)ch.size()){
      if(i >> j & 1){
        pro *= ch[j];
        bit_cnt++;
      }
    }
    now_ans[bit_cnt]+= pro;
  }
  bool is_same = true;
  rep(i,(ll)parsed.size()){
    if(parsed[i] != now_ans[i]){
      is_same = false;
    }
  }
  if(is_same){
    ans = ch;
  }

  // for(auto &p:ch){
  //   cout << p << " ";
  // }
  // cout << endl;
  se.insert(ch);
  return false;
}


void f(vector<ll> a,ll p){
  if(ans.size() == 1) return ;
  vector<ll> candi = divisor(p);
  ll now = 1;
  for(auto &q:a){
    now *= q;
  }
  if(a.size() == parsed.size()-2){
    a.push_back(parsed.back()/now);
    check(a);
  }else{
    rep(i,candi.size()){
      ll q = candi[i];
      a.push_back(q);
      f(a,p/q);
      a.pop_back();
      a.push_back(-q);
      f(a,p/q);
      a.pop_back();
    }
  }
}

int main(){
  string s;cin >> s;
  s += '=';
  State begin = s.begin();
  expression(begin);
  // for(auto &p:parsed){
  //   cout << p << endl;
  // }
  vector<ll> a;
  f(a,abs(parsed.back()));
  // for(auto & p:ans){
  //   cout << p << " ";
  // }
  // cout << endl;
  sort(all(ans));
  string kotae = "";
  for(auto &p:ans){
    if(p == 0){
      kotae += "x";
    }else{
      kotae += "(x";
      if(p > 0){
        kotae += "+";
      }
      kotae += to_string(p);
      kotae += ")";
    }
  }
  cout << kotae << endl;

}
accuracy: 1
time_ms: 20
memory_kb: 3544
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define ll long long
#define ld long double
#define print(t) cout << t << endl 
#define all(a)  (a).begin(),(a).end()
// << std::fixed << std::setprecision(0)
const ll INF = 1LL << 60;
 
template<class T> bool chmin(T& a, T b){
 if(a > b){
  a = b;
  return true;
 }
  return false;
}
 
template<class T> bool chmax(T& a, T b){
 if(a < b){
  a = b;
  return true;
 }
  return false;
}
  
ll lpow(ll x,ll n){
  ll ans = 1;
  while(n >0){
    if(n & 1)ans *= x;
    x *= x;
    n >>= 1;
  }
  return ans;
}

typedef string::const_iterator State;

class ParseError {};
//プロトタイプ宣言
void expression(State &begin);
void term(State &begin,bool plus);
void number(State &begin,bool plus);
void x(State &begin);
void consume(State &begin, char expected);

vector<ll> parsed;
vector<ll> ans;

void expression(State &begin){
  for(;;){
    if(*begin == 'x'){
      x(begin);
    }else if(*begin == '+'){
      term(begin,true);
    }else if(*begin == '-'){
      term(begin,false);
    }else{
      break;
    }
  }
}

void term(State &begin,bool plus){
  if(plus){
    consume(begin,'+');
  }else{
    consume(begin,'-');
  }
  number(begin,plus);
  if(*begin == 'x'){
    x(begin);
  }

}

void number(State & begin,bool plus){
    ll ret = 0;
  while(isdigit(*begin)){
    ret *= 10;
    ret += *begin - '0';
    begin++;
  }
  if(plus == false){
    ret *= -1;
  }
  //先読みをする
  ll id;
  if(*begin == '='){
    id = (ll)parsed.size()-1;
  }else{
    consume(begin,'x');
    if(*begin == '^'){
      begin++;
      ll p = (ll)(*begin - '0');
      id = (ll)parsed.size() - (p+1);
      begin--;
    }else{
      id = (ll)parsed.size()-2;
    }
    begin--;
  }
  parsed[id] = ret;
}

ll last = -1;
void x(State &begin){
  consume(begin,'x');
  if(*begin == '^'){
    consume(begin,'^');
    if(isdigit(*begin)){
      if(last == -1){
        last = *begin - '0';
        begin++;
        parsed.resize(last+1);
        parsed[0] = 1;
      }
      else {
        begin++;
        last--;
      }
    }
  }else{
    //x^3-x-1とかもゆるされるので
    // if(last != 2){
    //   cerr << "Expected '" << last -1 << "' but got '" << *begin << "'" << endl;
    //   cerr << "Rest string is '";
    //   while(*begin){
    //     cerr << *begin++;
    //   }
    //   cerr << "'" << endl;
    //   throw ParseError();
    // }
  }
}

void consume(State &begin, char expected){
  if(*begin == expected){
    begin++;
  }else{
    cerr << "Expected '" << expected << "' but got '" << *begin << "'" << endl;
    cerr << "Rest string is '";
    while(*begin){
      cerr << *begin++;
    }
    cerr << "'" << endl;
    throw ParseError();
  }
}

vector<ll> divisor(ll n){
  vector<ll> ret;
  for(ll i = 1;i * i <= n;i++){
    if(n % i == 0){
      ret.push_back(i);
      if(i * i != n)ret.push_back(n/i);
    }
  }
  //昇順
  sort(all(ret));
  return ret;
}

set<vector<ll>> se;
bool check(vector<ll> ch){
  sort(all(ch));
  if(se.count(ch))return false;
  vector<ll> now_ans((ll)parsed.size(),0);
  rep(i,1LL << ch.size()){
    ll pro = 1;
    ll bit_cnt = 0;
    rep(j,(ll)ch.size()){
      if(i >> j & 1){
        pro *= ch[j];
        bit_cnt++;
      }
    }
    now_ans[bit_cnt]+= pro;
  }
  bool is_same = true;
  rep(i,(ll)parsed.size()){
    if(parsed[i] != now_ans[i]){
      is_same = false;
    }
  }
  if(is_same){
    ans = ch;
  }

  // for(auto &p:ch){
  //   cout << p << " ";
  // }
  // cout << endl;
  se.insert(ch);
  return false;
}


void f(vector<ll> a,ll p){
  if(ans.size() == 1) return ;
  vector<ll> candi = divisor(p);
  ll now = 1;
  for(auto &q:a){
    now *= q;
  }
  if(a.size() == parsed.size()-2){
    a.push_back(parsed.back()/now);
    check(a);
  }else{
    rep(i,candi.size()){
      ll q = candi[i];
      a.push_back(q);
      f(a,p/q);
      a.pop_back();
      a.push_back(-q);
      f(a,p/q);
      a.pop_back();
    }
  }
}

int main(){
  string s;cin >> s;
  s += '=';
  State begin = s.begin();
  expression(begin);
  // for(auto &p:parsed){
  //   cout << p << endl;
  // }
  vector<ll> a;
  f(a,abs(parsed.back()));
  // for(auto & p:ans){
  //   cout << p << " ";
  // }
  // cout << endl;
  sort(all(ans));
  string kotae = "";
  for(auto &p:ans){
    if(p == 0){
      kotae += "x";
    }else{
      kotae += "(x";
      if(p > 0){
        kotae += "+";
      }
      kotae += to_string(p);
      kotae += ")";
    }
  }
  cout << kotae << endl;

}
accuracy: 0.9487179487179487
time_ms: 20
memory_kb: 3636
final_rank: 10

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-7;
const int inf=1e8;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
string s;
vi in;
int f(int a){
	if(s[a]=='+'||a==0)return 1;
	else if(s[a]=='-')return -1;
	int out=0;
	bool h=false;
	while(a&&isdigit(s[a-1]))a--;
	if(a&&s[a-1]=='-')h=true;
	while(isdigit(s[a])){
		out*=10;
		out+=s[a]-'0';
		a++;
	}
	if(h)out*=-1;
	return out;
}
vi ya;
int m;
vi out;
int dfs(int a,int b){
	if(a==m){
		//out
		loop(i,1,m+1){
			ll q=0;
			vi tmp(m);
			rep(j,i)tmp[j]=1;
			sort(all(tmp));
			do{
				ll qq=1;
				rep(j,m)if(tmp[j])qq*=out[j];
				q+=qq;
			}while(next_permutation(all(tmp)));
//			cout<<q<<" "<<in[m-i]<<endl;
			if(q!=in[m-i])return 0;
		}
/*		
		ll q=1;
		rep(i,m)q*=out[i];
		if(q!=in[0])return 0;
		q=0;
		rep(i,m)q+=out[i];
		if(q!=in[m-1])return 0;
		q=0;
		rep(i,m)rep(j,m)if(i!=j)q+=out[i]*out[j];
//		rep(i,m)cout<<" "<<out[i];cout<<endl;
		if(q/2!=in[m-2])return 0;
//*/		
		
		sort(all(out));
		bool h=true;
		rep(i,m-1)if(out[i]==out[i+1])h=false;
		if(!h)return 0;
		rep(i,m)printf("(x%+d)",out[i]);//cout<<" "<<out[i];cout<<endl;
		cout<<endl;
		return 1;
	}
	rep(i,ya.size())if(abs(in[0])%abs(b*ya[i])==0){
		out[a]=ya[i];
		if(dfs(a+1,b*ya[i]))return 1;
		out[a]=0;
	}
	return 0;
}
int main(){
	cin>>s;
	s="1"+s;
	in=vi(6);
	int n=s.size();
	rep(i,n)if(s[i]=='x'){
		if(s[i+1]=='^')in[s[i+2]-'0']=f(i-1);
		else in[1]=f(i-1);
	}
	in[0]=f(n-1);
	m=5;
	while(in[m]==0)m--;
	out=vi(m);
//	rep(i,6)cout<<" "<<in[i];cout<<endl;
	loop(i,1,2010)if(abs(in[0])%i==0){
		ya.pb(i);
		ya.pb(-i);
	}
//	rep(i,ya.size())cout<<" "<<ya[i];cout<<endl;
	dfs(0,1);
}


/*int n,m;
vvi in;
double h;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
double l,r;
bool f(){
	UnionFind uf(n);
	ll c=0,d=0;
	rep(i,m){
		double t=(double)in[i][2]/in[i][3];
		if(t<h){
			uf.unionSet(in[i][0],in[i][1]);
			c+=in[i][2];d+=in[i][3];
		}else{
			if(uf.findSet(in[i][0],in[i][1])==0){
				if((double)(c+in[i][2])/(d+in[i][3])<h)continue;
				cout<<c<<" "<<d<<endl;
				cout<<in[i][0]<<" "<<in[i][1]<<endl;
				uf.unionSet(in[i][0],in[i][1]);
				c+=in[i][2];d+=in[i][3];
			}
		}
	}
	cout<<l<<" "<<r<<" "<<h<<" "<<uf.size(0)<<endl;
	if(uf.size(0)==n)return true;
	return false;
}
int main(){
	cin>>n>>m;
	in=vvi(m,vi(4));
	rep(i,m)rep(j,4)cin>>in[i][j];
	rep(i,m)swap(in[i][2],in[i][3]);
	rep(i,m)rep(j,m)if(i!=j){
		if((double)in[i][3]/in[i][2]<(double)in[j][3]/in[j][2])swap(in[i],in[j]);
	}
	rep(i,m){rep(j,4)cout<<" "<<in[i][j];cout<<endl;}
	l=0,r=1e10+2;
	while(r-l>EPS){
		h=(l+r)/2;
		if(f())r=h;
		else l=h;
	}
	cout<<l<<" "<<r<<endl;
}
//*/
accuracy: 1
time_ms: 20
memory_kb: 3276
final_rank: 3

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-7;
const int inf=1e8;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
string s;
vi in;
int f(int a){
	if(!isdigit(s[a]))return 1;
	int out=0;
	bool h=false;
	while(a&&isdigit(s[a-1]))a--;
	if(a&&s[a-1]=='-')h=true;
	while(isdigit(s[a])){
		out*=10;
		out+=s[a]-'0';
		a++;
	}
	if(h)out*=-1;
	return out;
}
vi ya;
int m;
vi out;
int dfs(int a,int b){
	if(a==m){
		//out
		loop(i,1,m+1){
			ll q=0;
			vi tmp(m);
			rep(j,i)tmp[j]=1;
			sort(all(tmp));
			do{
				ll qq=1;
				rep(j,m)if(tmp[j])qq*=out[j];
				q+=qq;
			}while(next_permutation(all(tmp)));
//			cout<<q<<" "<<in[m-i]<<endl;
			if(q!=in[m-i])return 0;
		}
/*		
		ll q=1;
		rep(i,m)q*=out[i];
		if(q!=in[0])return 0;
		q=0;
		rep(i,m)q+=out[i];
		if(q!=in[m-1])return 0;
		q=0;
		rep(i,m)rep(j,m)if(i!=j)q+=out[i]*out[j];
//		rep(i,m)cout<<" "<<out[i];cout<<endl;
		if(q/2!=in[m-2])return 0;
//*/		
		
		sort(all(out));
		bool h=true;
		rep(i,m-1)if(out[i]==out[i+1])h=false;
		if(!h)return 0;
		rep(i,m)printf("(x%+d)",out[i]);//cout<<" "<<out[i];cout<<endl;
		cout<<endl;
		return 1;
	}
	rep(i,ya.size())if(abs(in[0])%abs(b*ya[i])==0){
		out[a]=ya[i];
		if(dfs(a+1,b*ya[i]))return 1;
		out[a]=0;
	}
	return 0;
}
int main(){
	cin>>s;
	s="1"+s;
	in=vi(6);
	int n=s.size();
	rep(i,n)if(s[i]=='x'){
		if(s[i+1]=='^')in[s[i+2]-'0']=f(i-1);
		else in[1]=f(i-1);
	}
	in[0]=f(n-1);
	m=5;
	while(in[m]==0)m--;
	out=vi(m);
//	rep(i,6)cout<<" "<<in[i];cout<<endl;
	loop(i,1,2010)if(abs(in[0])%i==0){
		ya.pb(i);
		ya.pb(-i);
	}
//	rep(i,ya.size())cout<<" "<<ya[i];cout<<endl;
	dfs(0,1);
}


/*int n,m;
vvi in;
double h;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
double l,r;
bool f(){
	UnionFind uf(n);
	ll c=0,d=0;
	rep(i,m){
		double t=(double)in[i][2]/in[i][3];
		if(t<h){
			uf.unionSet(in[i][0],in[i][1]);
			c+=in[i][2];d+=in[i][3];
		}else{
			if(uf.findSet(in[i][0],in[i][1])==0){
				if((double)(c+in[i][2])/(d+in[i][3])<h)continue;
				cout<<c<<" "<<d<<endl;
				cout<<in[i][0]<<" "<<in[i][1]<<endl;
				uf.unionSet(in[i][0],in[i][1]);
				c+=in[i][2];d+=in[i][3];
			}
		}
	}
	cout<<l<<" "<<r<<" "<<h<<" "<<uf.size(0)<<endl;
	if(uf.size(0)==n)return true;
	return false;
}
int main(){
	cin>>n>>m;
	in=vvi(m,vi(4));
	rep(i,m)rep(j,4)cin>>in[i][j];
	rep(i,m)swap(in[i][2],in[i][3]);
	rep(i,m)rep(j,m)if(i!=j){
		if((double)in[i][3]/in[i][2]<(double)in[j][3]/in[j][2])swap(in[i],in[j]);
	}
	rep(i,m){rep(j,4)cout<<" "<<in[i][j];cout<<endl;}
	l=0,r=1e10+2;
	while(r-l>EPS){
		h=(l+r)/2;
		if(f())r=h;
		else l=h;
	}
	cout<<l<<" "<<r<<endl;
}
//*/
accuracy: 0.9487179487179487
time_ms: 10
memory_kb: 3272
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-7;
const int inf=1e8;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
string s;
vi in;
int f(int a){
	int out=0;
	bool h=false;
	while(a&&isdigit(s[a-1]))a--;
	if(a&&s[a-1]=='-')h=true;
	while(isdigit(s[a])){
		out*=10;
		out+=s[a]-'0';
		a++;
	}
	if(h)out*=-1;
	return out;
}
vi ya;
int m;
vi out;
int dfs(int a,int b){
	if(a==m){
		//out
		loop(i,1,m+1){
			ll q=0;
			vi tmp(m);
			rep(j,i)tmp[j]=1;
			sort(all(tmp));
			do{
				ll qq=1;
				rep(j,m)if(tmp[j])qq*=out[j];
				q+=qq;
			}while(next_permutation(all(tmp)));
//			cout<<q<<" "<<in[m-i]<<endl;
			if(q!=in[m-i])return 0;
		}
/*		
		ll q=1;
		rep(i,m)q*=out[i];
		if(q!=in[0])return 0;
		q=0;
		rep(i,m)q+=out[i];
		if(q!=in[m-1])return 0;
		q=0;
		rep(i,m)rep(j,m)if(i!=j)q+=out[i]*out[j];
//		rep(i,m)cout<<" "<<out[i];cout<<endl;
		if(q/2!=in[m-2])return 0;
//*/		
		
		sort(all(out));
		bool h=true;
		rep(i,m-1)if(out[i]==out[i+1])h=false;
		if(!h)return 0;
		rep(i,m)printf("(x%+d)",out[i]);//cout<<" "<<out[i];cout<<endl;
		cout<<endl;
		return 1;
	}
	rep(i,ya.size())if(abs(in[0])%abs(b*ya[i])==0){
		out[a]=ya[i];
		if(dfs(a+1,b*ya[i]))return 1;
		out[a]=0;
	}
	return 0;
}
int main(){
	cin>>s;
	s="1"+s;
	in=vi(6);
	int n=s.size();
	rep(i,n)if(s[i]=='x'){
		if(s[i+1]=='^')in[s[i+2]-'0']=f(i-1);
		else in[1]=f(i-1);
	}
	in[0]=f(n-1);
	m=5;
	while(in[m]==0)m--;
	out=vi(m);
//	rep(i,6)cout<<" "<<in[i];cout<<endl;
	loop(i,1,2010)if(abs(in[0])%i==0){
		ya.pb(i);
		ya.pb(-i);
	}
//	rep(i,ya.size())cout<<" "<<ya[i];cout<<endl;
	dfs(0,1);
}


/*int n,m;
vvi in;
double h;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
double l,r;
bool f(){
	UnionFind uf(n);
	ll c=0,d=0;
	rep(i,m){
		double t=(double)in[i][2]/in[i][3];
		if(t<h){
			uf.unionSet(in[i][0],in[i][1]);
			c+=in[i][2];d+=in[i][3];
		}else{
			if(uf.findSet(in[i][0],in[i][1])==0){
				if((double)(c+in[i][2])/(d+in[i][3])<h)continue;
				cout<<c<<" "<<d<<endl;
				cout<<in[i][0]<<" "<<in[i][1]<<endl;
				uf.unionSet(in[i][0],in[i][1]);
				c+=in[i][2];d+=in[i][3];
			}
		}
	}
	cout<<l<<" "<<r<<" "<<h<<" "<<uf.size(0)<<endl;
	if(uf.size(0)==n)return true;
	return false;
}
int main(){
	cin>>n>>m;
	in=vvi(m,vi(4));
	rep(i,m)rep(j,4)cin>>in[i][j];
	rep(i,m)swap(in[i][2],in[i][3]);
	rep(i,m)rep(j,m)if(i!=j){
		if((double)in[i][3]/in[i][2]<(double)in[j][3]/in[j][2])swap(in[i],in[j]);
	}
	rep(i,m){rep(j,4)cout<<" "<<in[i][j];cout<<endl;}
	l=0,r=1e10+2;
	while(r-l>EPS){
		h=(l+r)/2;
		if(f())r=h;
		else l=h;
	}
	cout<<l<<" "<<r<<endl;
}
//*/
accuracy: 0.9487179487179487
time_ms: 10
memory_kb: 3276
final_rank: 9

code_snippet: #include<bits/stdc++.h>

using namespace std;

typedef long long int64;

vector< int64 > Divisor(int64 n)
{
  vector< int64 > ret;
  for(int64 i = 1; i * i <= n; i++) {
    if(n % i == 0) {
      ret.push_back(i);
      if(i * i != n) ret.push_back(n / i);
    }
  }
  sort(begin(ret), end(ret));
  return (ret);
}


int main()
{
  int aa[6] = {};
  string S;

  cin >> S;

  string buff;
  bool rev = false;
  for(int i = 0; i <= S.size(); i++) {
    if(i == S.size() || S[i] == '+' || S[i] == '-') {
      int fg = 0, ptr = 0;
      if(isdigit(buff[ptr])) {
        while(ptr < buff.size() && isdigit(buff[ptr])) {
          fg = fg * 10 + buff[ptr++] - '0';
        }
        if(ptr == buff.size()) {
          aa[0] += fg * (rev ? -1 : 1);
          continue;
        }
      }
      ++ptr;
      ++ptr;
      int ps = 0;
      while(ptr < buff.size() && isdigit(buff[ptr])) {
        ps = ps * 10 + buff[ptr++] - '0';
      }
      aa[max(1, ps)] = max(1, fg) * (rev ? -1 : 1);
      buff.clear();
      if(S[i] == '-') rev = true;
      else rev = false;
    } else {
      buff += S[i];
    }
  }

  int big = 0;
  for(int i = 0; i <= 5; i++) {
    if(aa[i] != 0) big = i;
  }


  vector< int64 > beet_puro = Divisor(abs(aa[0]));

  for(int64 i: beet_puro) {

    for(int64 j : beet_puro) {
      for(int64 k : beet_puro) {
        for(int64 l : beet_puro) {
          int64 fact = i * j * k * l;
          if(fact > abs(aa[0])) continue;
          if(aa[0] % fact != 0) continue;
          int64 m = abs(aa[0]) / fact;

          for(int n = 0; n < (1 << 5); n++) {
            bool ismatch = true;
            vector< int64 > vs = {i, j, k, l, m};


            for(int64 ei = 0; ei < 5; ei++) {
              if(ei >= big) {
                vs[ei] = 0;
              } else if((n >> ei) & 1) vs[ei] *= -1;

            }

            vector< int64 > proc(6, 0);
            for(int ei = 0; ei < (1 << 5); ei++) {
              int odd = __builtin_popcount(ei);
              int64 facto = 1;
              for(int latte = 0; latte < 5; latte++) {
                if((ei >> latte) & 1) facto *= vs[latte];
              }
              if(big - odd >= 0) proc[big - odd] += facto;
            }


            for(int malta = 0; malta < 5; malta++) {
              if(proc[malta] != aa[malta]) {
                ismatch = false;
                break;
              }
            }


            if(ismatch) {
              sort(begin(vs), end(vs));
              for(int uku = 0; uku < vs.size(); uku++) {
                if(vs[uku] == 0) continue;
                cout << "(x";
                if(vs[uku] > 0) cout << "+";
                cout << vs[uku] << ")";
              }
              cout << endl;
              return (0);
            }

          }
        }
      }
    }
  }


}
accuracy: 1
time_ms: 20
memory_kb: 3192
final_rank: 2

code_snippet: #include<bits/stdc++.h>

using namespace std;

typedef long long int64;

vector< int64 > Divisor(int64 n)
{
  vector< int64 > ret;
  for(int64 i = 1; i * i <= n; i++) {
    if(n % i == 0) {
      ret.push_back(i);
      if(i * i != n) ret.push_back(n / i);
    }
  }
  sort(begin(ret), end(ret));
  return (ret);
}


int main()
{
  int aa[6] = {};
  string S;

  cin >> S;

  string buff;
  bool rev = false;
  for(int i = 0; i <= S.size(); i++) {
    if(i == S.size() || S[i] == '+' || S[i] == '-') {
      int fg = 0, ptr = 0;
      if(isdigit(buff[ptr])) {
        while(ptr < buff.size() && isdigit(buff[ptr])) {
          fg = fg * 10 + buff[ptr++] - '0';
        }
        if(ptr == buff.size()) {
          aa[0] += fg * (rev ? -1 : 1);
          continue;
        }
      }
      ++ptr;
      ++ptr;
      int ps = 0;
      while(ptr < buff.size() && isdigit(buff[ptr])) {
        ps = ps * 10 + buff[ptr++] - '0';
      }
      aa[max(1, ps)] = max(1, fg) * (rev ? -1 : 1);
      buff.clear();
      if(S[i] == '-') rev = true;
    } else {
      buff += S[i];
    }
  }

  int big = 0;
  for(int i = 0; i <= 5; i++) {
    if(aa[i] != 0) big = i;
  }


  vector< int64 > beet_puro = Divisor(abs(aa[0]));

  for(int64 i: beet_puro) {

    for(int64 j : beet_puro) {
      for(int64 k : beet_puro) {
        for(int64 l : beet_puro) {
          int64 fact = i * j * k * l;
          if(fact > abs(aa[0])) continue;
          if(aa[0] % fact != 0) continue;
          int64 m = abs(aa[0]) / fact;

          for(int n = 0; n < (1 << 5); n++) {
            bool ismatch = true;
            vector< int64 > vs = {i, j, k, l, m};


            for(int64 ei = 0; ei < 5; ei++) {
              if(ei >= big) {
                vs[ei] = 0;
              } else if((n >> ei) & 1) vs[ei] *= -1;

            }

            vector< int64 > proc(6, 0);
            for(int ei = 0; ei < (1 << 5); ei++) {
              int odd = __builtin_popcount(ei);
              int64 facto = 1;
              for(int latte = 0; latte < 5; latte++) {
                if((ei >> latte) & 1) facto *= vs[latte];
              }
              if(big - odd >= 0) proc[big - odd] += facto;
            }


            for(int malta = 0; malta < 5; malta++) {
              if(proc[malta] != aa[malta]) {
                ismatch = false;
                break;
              }
            }


            if(ismatch) {
              sort(begin(vs), end(vs));
              for(int uku = 0; uku < vs.size(); uku++) {
                if(vs[uku] == 0) continue;
                cout << "(x";
                if(vs[uku] > 0) cout << "+";
                cout << vs[uku] << ")";
              }
              cout << endl;
              return (0);
            }

          }
        }
      }
    }
  }


}
accuracy: 0.1282051282051282
time_ms: 10
memory_kb: 3140
final_rank: 12

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-7;
const int inf=1e8;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
string s;
vi in;
int f(int a){
	int out=0;
	bool h=false;
	while(a&&isdigit(s[a-1]))a--;
	if(a&&s[a-1]=='-')h=true;
	while(isdigit(s[a])){
		out*=10;
		out+=s[a]-'0';
		a++;
	}
	if(h)out*=-1;
	return out;
}
vi ya;
int m;
vi out;
int dfs(int a,int b){
	if(a==m){
		//out
		loop(i,1,m+1){
			ll q=0;
			vi tmp(m);
			rep(j,i)tmp[j]=1;
			sort(all(tmp));
			do{
				ll qq=1;
				rep(j,m)if(tmp[j])qq*=out[j];
				q+=qq;
			}while(next_permutation(all(tmp)));
//			cout<<q<<" "<<in[m-i]<<endl;
			if(q!=in[m-i])return 0;
		}
/*		
		ll q=1;
		rep(i,m)q*=out[i];
		if(q!=in[0])return 0;
		q=0;
		rep(i,m)q+=out[i];
		if(q!=in[m-1])return 0;
		q=0;
		rep(i,m)rep(j,m)if(i!=j)q+=out[i]*out[j];
//		rep(i,m)cout<<" "<<out[i];cout<<endl;
		if(q/2!=in[m-2])return 0;
//*/		
		
		sort(all(out));
		rep(i,m)printf("(x%+d)",out[i]);//cout<<" "<<out[i];cout<<endl;
		cout<<endl;
		return 1;
	}
	rep(i,ya.size())if(abs(in[0])%abs(b*ya[i])==0){
		out[a]=ya[i];
		if(dfs(a+1,b*ya[i]))return 1;
		out[a]=0;
	}
	return 0;
}
int main(){
	cin>>s;
	s="1"+s;
	in=vi(6);
	int n=s.size();
	rep(i,n)if(s[i]=='x'){
		if(s[i+1]=='^')in[s[i+2]-'0']=f(i-1);
		else in[1]=f(i-1);
	}
	in[0]=f(n-1);
	m=5;
	while(in[m]==0)m--;
	out=vi(m);
//	rep(i,6)cout<<" "<<in[i];cout<<endl;
	loop(i,1,2010)if(abs(in[0])%i==0){
		ya.pb(i);
		ya.pb(-i);
	}
//	rep(i,ya.size())cout<<" "<<ya[i];cout<<endl;
	dfs(0,1);
}


/*int n,m;
vvi in;
double h;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
double l,r;
bool f(){
	UnionFind uf(n);
	ll c=0,d=0;
	rep(i,m){
		double t=(double)in[i][2]/in[i][3];
		if(t<h){
			uf.unionSet(in[i][0],in[i][1]);
			c+=in[i][2];d+=in[i][3];
		}else{
			if(uf.findSet(in[i][0],in[i][1])==0){
				if((double)(c+in[i][2])/(d+in[i][3])<h)continue;
				cout<<c<<" "<<d<<endl;
				cout<<in[i][0]<<" "<<in[i][1]<<endl;
				uf.unionSet(in[i][0],in[i][1]);
				c+=in[i][2];d+=in[i][3];
			}
		}
	}
	cout<<l<<" "<<r<<" "<<h<<" "<<uf.size(0)<<endl;
	if(uf.size(0)==n)return true;
	return false;
}
int main(){
	cin>>n>>m;
	in=vvi(m,vi(4));
	rep(i,m)rep(j,4)cin>>in[i][j];
	rep(i,m)swap(in[i][2],in[i][3]);
	rep(i,m)rep(j,m)if(i!=j){
		if((double)in[i][3]/in[i][2]<(double)in[j][3]/in[j][2])swap(in[i],in[j]);
	}
	rep(i,m){rep(j,4)cout<<" "<<in[i][j];cout<<endl;}
	l=0,r=1e10+2;
	while(r-l>EPS){
		h=(l+r)/2;
		if(f())r=h;
		else l=h;
	}
	cout<<l<<" "<<r<<endl;
}
//*/
accuracy: 0.9487179487179487
time_ms: 10
memory_kb: 3272
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-7;
const int inf=1e8;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
string s;
vi in;
int f(int a){
	int out=0;
	bool h=false;
	while(a&&isdigit(s[a-1]))a--;
	if(a&&s[a-1]=='-')h=true;
	while(isdigit(s[a])){
		out*=10;
		out+=s[a]-'0';
		a++;
	}
	if(h)out*=-1;
	return out;
}
vi ya;
int m;
vi out;
int dfs(int a,int b){
	if(a==m){
		//out
		ll q=1;
		rep(i,m)q*=out[i];
		if(q!=in[0])return 0;
		q=0;
		rep(i,m)q+=out[i];
		if(q!=in[m-1])return 0;
		q=0;
		rep(i,m)rep(j,m)if(i!=j)q+=out[i]*out[j];
//		rep(i,m)cout<<" "<<out[i];cout<<endl;
		if(q/2!=in[m-2])return 0;
		sort(all(out));
		rep(i,m)printf("(x%+d)",out[i]);//cout<<" "<<out[i];cout<<endl;
		cout<<endl;
		return 1;
	}
	rep(i,ya.size())if(abs(in[0])%abs(b*ya[i])==0){
		out[a]=ya[i];
		if(dfs(a+1,b*ya[i]))return 1;
		out[a]=0;
	}
	return 0;
}
int main(){
	cin>>s;
	s="1"+s;
	in=vi(6);
	int n=s.size();
	rep(i,n)if(s[i]=='x'){
		if(s[i+1]=='^')in[s[i+2]-'0']=f(i-1);
		else in[1]=f(i-1);
	}
	in[0]=f(n-1);
	m=5;
	while(in[m]==0)m--;
	out=vi(m);
//	rep(i,6)cout<<" "<<in[i];cout<<endl;
	loop(i,1,2010)if(abs(in[0])%i==0){
		ya.pb(i);
		ya.pb(-i);
	}
//	rep(i,ya.size())cout<<" "<<ya[i];cout<<endl;
	dfs(0,1);
}


/*int n,m;
vvi in;
double h;
struct UnionFind{
    vector<int> data;
    UnionFind(int size) : data(size, -1) {}
    bool unionSet(int x,int y){
        x=root(x);y=root(y);
        if(x==y)return 0;
        if(data[y]<data[x])swap(x,y);
        data[x]+=data[y],data[y]=x;
        return 1;
    }
    bool findSet(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0 ? x : data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};
double l,r;
bool f(){
	UnionFind uf(n);
	ll c=0,d=0;
	rep(i,m){
		double t=(double)in[i][2]/in[i][3];
		if(t<h){
			uf.unionSet(in[i][0],in[i][1]);
			c+=in[i][2];d+=in[i][3];
		}else{
			if(uf.findSet(in[i][0],in[i][1])==0){
				if((double)(c+in[i][2])/(d+in[i][3])<h)continue;
				cout<<c<<" "<<d<<endl;
				cout<<in[i][0]<<" "<<in[i][1]<<endl;
				uf.unionSet(in[i][0],in[i][1]);
				c+=in[i][2];d+=in[i][3];
			}
		}
	}
	cout<<l<<" "<<r<<" "<<h<<" "<<uf.size(0)<<endl;
	if(uf.size(0)==n)return true;
	return false;
}
int main(){
	cin>>n>>m;
	in=vvi(m,vi(4));
	rep(i,m)rep(j,4)cin>>in[i][j];
	rep(i,m)swap(in[i][2],in[i][3]);
	rep(i,m)rep(j,m)if(i!=j){
		if((double)in[i][3]/in[i][2]<(double)in[j][3]/in[j][2])swap(in[i],in[j]);
	}
	rep(i,m){rep(j,4)cout<<" "<<in[i][j];cout<<endl;}
	l=0,r=1e10+2;
	while(r-l>EPS){
		h=(l+r)/2;
		if(f())r=h;
		else l=h;
	}
	cout<<l<<" "<<r<<endl;
}
//*/
accuracy: 0.9487179487179487
time_ms: 10
memory_kb: 3272
final_rank: 6

code_snippet: #include<iostream>
#include<sstream>
#include<vector>
#include<deque>
#include<cstdio>
#include<set>
#include<cassert>
#include<algorithm>

#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)

using namespace std;
typedef long long ll;
const bool debug = false;

deque<string> split(string s) {
  deque<string> deq;
  int n = (int)s.size();
  int sp = 0;
  rep(i,n) {
    if( s[i] == 'x' ) {
      int ep = i;
      if( i+1 < n && s[i+1] == '^' ) {
	ep = i+2;
	assert( i + 2 < n );
      }
      deq.push_back(s.substr(sp,ep-sp+1));
      sp = ep + 1;
    }
  }
  if( sp != n ) {
    deq.push_back(s.substr(sp));
  }
  return deq;
}

string getCoef(string s) {

  bool minus = ( s[0] == '-' );

  rep(i,(int)s.size()) {
    if( s[i] == '+' || s[i] == '-' ) {
      s[i] = ' ';
    }
  }
  stringstream ss2;
  ss2 << s;
  ss2 >> s;


  bool found = false;
  if( s[0] == 'x' ) {
    if( minus ) return "-1";
    return "1";
  }
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      s[i] = ' ';
      found = true;
    }
  }
  if( !found ) {
    if( minus ) s = "-" + s;
    return s;
  }
  stringstream ss;
  ss << s;
  string ret;
  ss >> ret;
  if( minus ) {
    ret = "-" + ret;
  }
  return ret;
}

int getPcoef(string s) {
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      if( i + 1 < (int)s.size() && s[i+1] == '^' ) {
	return s[i+2] - '0';
      } else {
	return 1;
      }
    }
  }
  return 0;
}

bool check(ll x,deque<string> &deq) {
  if( debug ) {
    puts("");
    cout << "check [[ " << x << "]]" << endl;
  }
  ll res = 0;
  rep(i,(int)deq.size()) {
    ll cost = 0;
    string s = deq[i];
    string coef = getCoef(s);
    int pcoef = getPcoef(s);
    if( debug ) {
      cout << deq[i] << " --> " << coef << " * x^[" << pcoef << "]" << endl;
    }
    
    ll v = atoll(coef.c_str());
    if( debug )cout << "v = " << v << endl;
    ll tmp = 1;
    rep(_,pcoef) tmp *= x;
    cost = v * tmp;
    if( debug ){
      cout << "cost = " << cost << endl;
    }
    res += cost;
  }
  return res == 0;
}

int getDegree(string  s) {
  int ret = 0;
  int n = (int)s.size();
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      if( i+1 < n && s[i+1] == '^' ) {
	assert( i + 2 < n );
	ret = max(ret,s[i+2]-'0');
      } else {
	ret = max(ret,1);
      }
    }
  }
  return ret;
}

void compute(string s) {
  int deg = getDegree(s);
  if( debug ) cout << "degree = " << deg << endl;
  deque<string> deq = split(s);
  if( debug ) {
    cout << "split --" << endl;
    rep(i,(int)deq.size()) {
      cout << deq[i] << " :: ";
    } puts("");
  }

  set<int> S;
  rep(i,(int)deq.size()) {
    S.insert(getPcoef(deq[i]));
  }
  assert( (int)S.size() == (int)deq.size() );


  /*
  cout << check(-2,deq) << endl;
  return;
  */

  vector<ll> ans;
  for(ll i=1;;++i) {
    if( check(i,deq) ) ans.push_back(i);
    if( check(-i,deq) ) ans.push_back(-i);
    if( (int)ans.size() >= deg ) break;
  }  
  sort(ans.begin(),ans.end(),greater<int>());
  rep(i,(int)ans.size()) {
    if( ans[i] == 0) {
      cout <<"x";
    } else {
      cout << "(x";
      if(ans[i]<0LL) cout << "+" << -ans[i] << ")";
      else           cout  << "-" << ans[i] << ")";
    }
  } puts("");
}

int main() {
  string s;
  cin >> s;
  compute(s);
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3156
final_rank: 1

code_snippet: #include<iostream>
#include<sstream>
#include<vector>
#include<deque>
#include<cstdio>
#include<cassert>
#include<algorithm>

#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)

using namespace std;
typedef long long ll;
const bool debug = false;

deque<string> split(string s) {
  deque<string> deq;
  int n = (int)s.size();
  int sp = 0;
  rep(i,n) {
    if( s[i] == 'x' ) {
      int ep = i;
      if( i+1 < n && s[i+1] == '^' ) {
	ep = i+2;
	assert( i + 2 < n );
      }
      deq.push_back(s.substr(sp,ep-sp+1));
      sp = ep + 1;
    }
  }
  if( sp != n ) {
    deq.push_back(s.substr(sp));
  }
  return deq;
}

string getCoef(string s) {
  bool found = false;
  if( s[0] == 'x' ) return "1";
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      s[i] = ' ';
      found = true;
    }
  }
  if( !found ) {
    return s;
  }
  stringstream ss;
  ss << s;
  string ret;
  ss >> ret;
  return ret;
}

int getPcoef(string s) {
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      if( i + 1 < (int)s.size() && s[i+1] == '^' ) {
	return s[i+2] - '0';
      } else {
	return 1;
      }
    }
  }
  return 0;
}

bool check(ll x,deque<string> &deq) {
  if( debug ) {
    puts("");
    cout << "check [[ " << x << "]]" << endl;
  }
  ll res = 0;
  rep(i,(int)deq.size()) {
    ll cost = 0;
    string s = deq[i];
    string coef = getCoef(s);
    int pcoef = getPcoef(s);
    if( debug ) {
      cout << deq[i] << " --> " << coef << " * x^[" << pcoef << "]" << endl;
    }
    ll v = atoll(coef.c_str());
    if( debug )cout << "v = " << v << endl;
    ll tmp = 1;
    rep(_,pcoef) tmp *= x;
    cost = v * tmp;
    if( debug ){
      cout << "cost = " << cost << endl;
    }
    res += cost;
  }
  return res == 0;
}

int getDegree(string  s) {
  int ret = 0;
  int n = (int)s.size();
  rep(i,(int)s.size()) {
    if( s[i] == 'x' ) {
      if( i+1 < n && s[i+1] == '^' ) {
	assert( i + 2 < n );
	ret = max(ret,s[i+2]-'0');
      } else {
	ret = max(ret,1);
      }
    }
  }
  return ret;
}

void compute(string s) {
  int deg = getDegree(s);
  if( debug ) cout << "degree = " << deg << endl;
  deque<string> deq = split(s);
  if( debug ) {
    cout << "split --" << endl;
    rep(i,(int)deq.size()) {
      cout << deq[i] << " :: ";
    } puts("");
  }

  /*
  cout << check(-1,deq) << endl;
  return;
  */

  vector<ll> ans;
  for(ll i=0;i<=300000;++i) {
    if( check(i,deq) ) ans.push_back(i);
    if( i != 0 && check(-i,deq) ) ans.push_back(-i);
    if( (int)ans.size() >= deg ) break;
  }  
  sort(ans.begin(),ans.end(),greater<int>());
  rep(i,(int)ans.size()) {
    if( ans[i] == 0) {
      cout <<"x";
    } else {
      cout << "(x";
      if(ans[i]<0LL) cout << "+" << -ans[i] << ")";
      else           cout  << "-" << ans[i] << ")";
    }
  } puts("");
}

int main() {
  string s;
  cin >> s;
  compute(s);
  return 0;
}
accuracy: 0.9487179487179487
time_ms: 470
memory_kb: 3192
final_rank: 11