void efcode(void) { TWORD t; NODE *p, *q; /* code for the end of a function */ if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN) return; t = PTR+BTYPE(cftnsp->stype); /* Create struct assignment */ q = tempnode(strtemp, t, 0, cftnsp->sap); q = buildtree(UMUL, q, NIL); p = block(REG, NIL, NIL, t, 0, cftnsp->sap); regno(p) = R0; p = buildtree(UMUL, p, NIL); p = buildtree(ASSIGN, q, p); ecomp(p); /* put hidden arg in r0 on return */ q = tempnode(strtemp, INT, 0, 0); p = block(REG, NIL, NIL, INT, 0, 0); regno(p) = R0; ecomp(buildtree(ASSIGN, p, q)); }
void bfcode(struct symtab **sp, int cnt) { int i, off; NODE *p, *q; struct symtab *sym; /* Process the first six arguments. */ for (i=0; i < cnt && i < 6; i++) { sym = sp[i]; q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->sap); q->n_rval = RETREG_PRE(sym->stype) + i; p = tempnode(0, sym->stype, sym->sdf, sym->sap); sym->soffset = regno(p); sym->sflags |= STNODE; p = buildtree(ASSIGN, p, q); ecomp(p); } /* Process the remaining arguments. */ for (off = V9RESERVE; i < cnt; i++) { sym = sp[i]; p = tempnode(0, sym->stype, sym->sdf, sym->sap); off = ALIGN(off, (tlen(p) - 1)); sym->soffset = off * SZCHAR; off += tlen(p); p = buildtree(ASSIGN, p, nametree(sym)); sym->soffset = regno(p->n_left); sym->sflags |= STNODE; ecomp(p); } }
void bfcode(struct symtab **sp, int n) { struct symtab *sp2; NODE *p, *q; int i; if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) { /* Move return address into temporary */ p = tempnode(0, INT, 0, 0); strtemp = regno(p); q = block(REG, 0, 0, INT, 0, 0); regno(q) = R1; ecomp(buildtree(ASSIGN, p, q)); } if (xtemps == 0) return; /* put arguments in temporaries */ for (i = 0; i < n; i++) { if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY || cisreg(sp[i]->stype) == 0) continue; if (cqual(sp[i]->stype, sp[i]->squal) & VOL) continue; sp2 = sp[i]; p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->sap); p = buildtree(ASSIGN, p, nametree(sp2)); sp[i]->soffset = regno(p->n_left); sp[i]->sflags |= STNODE; ecomp(p); } }
/* * Move args to registers and emit expressions bottom-up. */ static void fixargs(NODE *p) { NODE *r; if (p->n_op == CM) { fixargs(p->n_left); r = p->n_right; if (r->n_op == STARG) regnum = 9; /* end of register list */ else if (regnum + szty(r->n_type) > 8) p->n_right = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_sue); else p->n_right = buildtree(ASSIGN, mkreg(r, regnum), r); } else { if (p->n_op == STARG) { regnum = 9; /* end of register list */ } else { r = talloc(); *r = *p; r = buildtree(ASSIGN, mkreg(r, regnum), r); *p = *r; nfree(r); } r = p; } regnum += szty(r->n_type); }
/* * code for the beginning of a function; a is an array of * indices in stab for the arguments; n is the number */ void bfcode(struct symtab **sp, int cnt) { NODE *p, *q; int i, n; if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) { uerror("no struct return yet"); } /* recalculate the arg offset and create TEMP moves */ for (n = 1, i = 0; i < cnt; i++) { if (n < 8) { p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue); q = block(REG, NIL, NIL, sp[i]->stype, sp[i]->sdf, sp[i]->ssue); q->n_rval = n; p = buildtree(ASSIGN, p, q); sp[i]->soffset = regno(p->n_left); sp[i]->sflags |= STNODE; ecomp(p); } else { sp[i]->soffset += SZINT * n; if (xtemps) { /* put stack args in temps if optimizing */ p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue); p = buildtree(ASSIGN, p, nametree(sp[i])); sp[i]->soffset = regno(p->n_left); sp[i]->sflags |= STNODE; ecomp(p); } } n += szty(sp[i]->stype); } }
/* * Allocate off bits on the stack. p is a tree that when evaluated * is the multiply count for off, t is a storeable node where to write * the allocated address. */ void spalloc(NODE *t, NODE *p, OFFSZ off) { NODE *sp; p = buildtree(MUL, p, bcon(off/SZCHAR)); p = buildtree(PLUS, p, bcon(30)); p = buildtree(AND, p, xbcon(-16, NULL, UNSIGNED)); p = cast(p, UNSIGNED, 0); /* sub the size from sp */ sp = block(REG, NIL, NIL, UNSIGNED+PTR, 0, 0); slval(sp, 0); sp->n_rval = STKREG; p = (buildtree(MINUSEQ, sp, p)); ecomp(p); /* save the address of sp */ sp = block(REG, NIL, NIL, PTR+UNSIGNED, t->n_df, t->n_ap); slval(sp, 0); sp->n_rval = STKREG; t->n_type = sp->n_type; p = (buildtree(ASSIGN, t, sp)); /* Emit! */ ecomp(p); }
/* * Create a reference for an extern variable. */ static NODE * picext(NODE *p) { NODE *q, *r; struct symtab *sp; char *name; q = tempnode(gotnr, PTR|VOID, 0, 0); name = getexname(p->n_sp); #ifdef notdef struct attr *ga; if ((ga = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) && strcmp(ga->sarg(0), "hidden") == 0) { /* For hidden vars use GOTOFF */ sp = picsymtab("", name, "@GOTOFF"); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ nfree(p); return q; } #endif sp = picsymtab("", name, "@GOT"); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, PTR|VOID, 0, 0); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ nfree(p); return q; }
void buildtree(int s, int e,int & maximal, int & minimal) { if (e - s + 1 <= 0) { maximal = minimal = -1; return; } if (e - s + 1 == 1) { maximal = minimal = input[e]; return; } if (e - s + 1 == 2) { maximal = input[s] > input[e] ? input[s] : input[e]; minimal = input[s] > input[e] ? input[e] : input[s]; return; } int temp = (s + e) / 2; arr[temp].max = input[temp]; arr[temp].min = input[temp]; int i, j; buildtree(s, temp - 1, i, j); if (i >= 0 && j >= 0) { if (i > arr[temp].max) arr[temp].max = i; if (j < arr[temp].min) arr[temp].min = j; } buildtree(temp + 1, e, i, j); if (i >= 0 && j >= 0) { if (i > arr[temp].max) arr[temp].max = i; if (j < arr[temp].min) arr[temp].min = j; } maximal = arr[temp].max; minimal = arr[temp].min; }
/* * Builds a balanced tree from the N first elements of the * given sorted list. Assigns the first, root and last node * pointers. */ static void buildtree(list_t *list, int N, treenode_t **first, treenode_t **root, treenode_t **last) { if (N == 1) { *first = *root = *last = newnode(list_popfirst(list)); } else if (N == 2) { *first = *root = newnode(list_popfirst(list)); *last = (*root)->right = (*root)->next = newnode(list_popfirst(list)); } else if (N > 2) { treenode_t *left; /* root of left subtree */ treenode_t *leftlast; /* last node in left subtree */ treenode_t *right; /* root of right subtree */ treenode_t *rightfirst; /* first node in right subtree */ buildtree(list, N - N/2 - 1, first, &left, &leftlast); *root = *last = newnode(list_popfirst(list)); (*root)->left = left; (*root)->level = left->level + 1; leftlast->next = *root; buildtree(list, N/2, &rightfirst, &right, last); (*root)->right = right; (*root)->next = rightfirst; } }
/* * code for the end of a function * deals with struct return here */ void efcode(void) { NODE *p, *q; int tempnr; int ty; if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN) return; ty = cftnsp->stype - FTN; q = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap); q->n_rval = V0; p = tempnode(0, INCREF(ty), 0, cftnsp->sap); tempnr = regno(p); p = buildtree(ASSIGN, p, q); ecomp(p); q = tempnode(tempnr, INCREF(ty), 0, cftnsp->sap); q = buildtree(UMUL, q, NIL); p = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap); p = buildtree(UMUL, p, NIL); p = buildtree(ASSIGN, p, q); ecomp(p); q = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap); p = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap); p->n_rval = V0; p = buildtree(ASSIGN, p, q); ecomp(p); }
/* * va_start(ap, last) implementation. * * f is the NAME node for this builtin function. * a is the argument list containing: * CM * ap last * * It turns out that this is easy on MIPS. Just write the * argument registers to the stack in va_arg_start() and * use the traditional method of walking the stackframe. */ NODE * mips_builtin_stdarg_start(NODE *f, NODE *a, TWORD t) { NODE *p, *q; int sz = 1; /* check num args and type */ if (a == NULL || a->n_op != CM || a->n_left->n_op == CM || !ISPTR(a->n_left->n_type)) goto bad; /* must first deal with argument size; use int size */ p = a->n_right; if (p->n_type < INT) { /* round up to word */ sz = SZINT / tsize(p->n_type, p->n_df, p->n_ap); } p = buildtree(ADDROF, p, NIL); /* address of last arg */ p = optim(buildtree(PLUS, p, bcon(sz))); q = block(NAME, NIL, NIL, PTR+VOID, 0, 0); q = buildtree(CAST, q, p); p = q->n_right; nfree(q->n_left); nfree(q); p = buildtree(ASSIGN, a->n_left, p); tfree(f); nfree(a); return p; bad: uerror("bad argument to __builtin_stdarg_start"); return bcon(0); }
static NODE * builtin_stdarg_start(const struct bitable *bt, NODE *a) { NODE *p, *q; int sz; /* must first deal with argument size; use int size */ p = a->n_right; if (p->n_type < INT) { sz = (int)(SZINT/tsize(p->n_type, p->n_df, p->n_ap)); } else sz = 1; /* do the real job */ p = buildtree(ADDROF, p, NIL); /* address of last arg */ #ifdef BACKAUTO p = optim(buildtree(PLUS, p, bcon(sz))); /* add one to it (next arg) */ #else p = optim(buildtree(MINUS, p, bcon(sz))); /* add one to it (next arg) */ #endif q = block(NAME, NIL, NIL, PTR+VOID, 0, 0); /* create cast node */ q = buildtree(CAST, q, p); /* cast to void * (for assignment) */ p = q->n_right; nfree(q->n_left); nfree(q); p = buildtree(ASSIGN, a->n_left, p); /* assign to ap */ nfree(a); return p; }
/* setup a float param on the stack * used by bfcode() */ static void param_float(struct symtab *sym, int *argofsp, int dotemps) { NODE *p, *q, *t; int tmpnr; /* * we have to dump the float from the general register * into a temp, since the register allocator doesn't like * floats to be in CLASSA. This may not work for -xtemps. */ t = tempnode(0, INT, 0, 0); tmpnr = regno(t); q = block(REG, NIL, NIL, INT, 0, 0); q->n_rval = R0 + (*argofsp)++; p = buildtree(ASSIGN, t, q); ecomp(p); if (dotemps) { sym->soffset = tmpnr; sym->sflags |= STNODE; } else { q = tempnode(tmpnr, sym->stype, sym->sdf, sym->sap); p = nametree(sym); p = buildtree(ASSIGN, p, q); ecomp(p); } }
NODE * amd64_builtin_va_copy(NODE *f, NODE *a, TWORD t) { tfree(f); f = buildtree(ASSIGN, buildtree(UMUL, a->n_left, NIL), buildtree(UMUL, a->n_right, NIL)); nfree(a); return f; }
static NODE * moveargs(NODE *p, int *regp) { NODE *r, **rp; int lastreg; int reg; if (p->n_op == CM) { p->n_left = moveargs(p->n_left, regp); r = p->n_right; rp = &p->n_right; } else { r = p; rp = &p; } lastreg = A0 + nargregs - 1; reg = *regp; if (reg > lastreg && r->n_op != STARG) *rp = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_ap); else if (r->n_op == STARG) { *rp = movearg_struct(r, p, regp); } else if (DEUNSIGN(r->n_type) == LONGLONG) { *rp = movearg_64bit(r, regp); } else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) { /* XXX bounce in and out of temporary to change to longlong */ NODE *t1 = tempnode(0, LONGLONG, 0, 0); int tmpnr = regno(t1); NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap); t1 = movearg_64bit(t1, regp); r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap); if (p->n_op == CM) { p->n_left = buildtree(CM, p->n_left, t1); p->n_right = r; } else { p = buildtree(CM, t1, r); } } else if (r->n_type == FLOAT) { /* XXX bounce in and out of temporary to change to int */ NODE *t1 = tempnode(0, INT, 0, 0); int tmpnr = regno(t1); NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap); t1 = movearg_32bit(t1, regp); r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap); if (p->n_op == CM) { p->n_left = buildtree(CM, p->n_left, t1); p->n_right = r; } else { p = buildtree(CM, t1, r); } } else { *rp = movearg_32bit(r, regp); } return p; }
static NODE * builtin_bswap16(const struct bitable *bt, NODE *a) { NODE *f, *t1, *t2; t1 = buildtree(LS, buildtree(AND, ccopy(a), bcon(255)), bcon(8)); t2 = buildtree(AND, buildtree(RS, a, bcon(8)), bcon(255)); f = buildtree(OR, t1, t2); return f; }
void buildtree(int id,int l,int r) { if(l==r) st[id]=a[l] ; else{ int mid=(l+r)/2; buildtree(2*id,l,mid); buildtree((2*id)+1,mid+1,r); st[id]=st[2*id]+st[(2*id)+1]; } }
NODE * amd64_builtin_va_copy(const struct bitable *bt, NODE *a) { NODE *f; f = buildtree(ASSIGN, buildtree(UMUL, a->n_left, NIL), buildtree(UMUL, a->n_right, NIL)); nfree(a); return f; }
/* * Allocate off bits on the stack. p is a tree that when evaluated * is the multiply count for off, t is a NAME node where to write * the allocated address. */ void spalloc(NODE *t, NODE *p, OFFSZ off) { NODE *sp; if ((off % SZINT) == 0) p = buildtree(MUL, p, bcon(off/SZINT)); else if ((off % SZSHORT) == 0) { p = buildtree(MUL, p, bcon(off/SZSHORT)); p = buildtree(PLUS, p, bcon(1)); p = buildtree(RS, p, bcon(1)); } else if ((off % SZCHAR) == 0) { p = buildtree(MUL, p, bcon(off/SZCHAR)); p = buildtree(PLUS, p, bcon(3)); p = buildtree(RS, p, bcon(2)); } else cerror("roundsp"); /* save the address of sp */ sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue); sp->n_lval = 0; sp->n_rval = STKREG; t->n_type = sp->n_type; ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */ /* add the size to sp */ sp = block(REG, NIL, NIL, p->n_type, 0, 0); sp->n_lval = 0; sp->n_rval = STKREG; ecomp(buildtree(PLUSEQ, sp, p)); }
struct node *buildtree(int index, char *a) { struct node *temp = NULL; if (a[index] != '\0') { temp = (struct node *)malloc(sizeof(struct node)); temp->left = buildtree( 2*index + 1, a); temp->data = a[index]; temp->right = buildtree( 2*index + 2, a); } return temp; }
struct node * buildtree ( int n ) { struct node *temp = NULL ; if ( a[n] != '\0' ) { temp = ( struct node * ) malloc ( sizeof ( struct node ) ) ; temp -> left = buildtree ( 2 * n + 1 ) ; temp -> data = a[n] ; temp -> right = buildtree ( 2 * n + 2 ) ; } return temp ; }
struct node * buildtree ( int index ) { struct node *temp = NULL ; if ( index != -1 ) { temp = ( struct node * ) malloc ( sizeof ( struct node ) ) ; temp -> left = buildtree ( lc[index] ) ; temp -> data = arr[index] ; temp -> right = buildtree ( rc[index] ) ; } return temp ; }
struct NODE *buildtree(int index){ struct NODE *temp; if(d[index] == '\0') return NULL; temp = (struct NODE *)malloc(sizeof(struct NODE)); temp->data = d[index]; temp->l = buildtree(2*index + 1); temp->r = buildtree(2*index + 2); return temp; }
NODE * funcode(NODE *p) { NODE *r, *l; int reg = 0, stacksize = 0; r = l = 0; p->n_right = moveargs(p->n_right, ®, &stacksize); /* * This is a particularly gross and inefficient way to handle * argument overflows. First, we calculate how much stack space * we need in moveargs(). Then we assign it by moving %sp, make * the function call, and then move %sp back. * * What we should be doing is getting the maximum of all the needed * stacksize values to the prologue and doing it all in the "save" * instruction. */ if (stacksize != 0) { stacksize = V9STEP(stacksize); /* 16-bit alignment. */ r = block(REG, NIL, NIL, INT, 0, 0); r->n_lval = 0; r->n_rval = SP; r = block(MINUS, r, bcon(stacksize), INT, 0, 0); l = block(REG, NIL, NIL, INT, 0, 0); l->n_lval = 0; l->n_rval = SP; r = buildtree(ASSIGN, l, r); p = buildtree(COMOP, r, p); r = block(REG, NIL, NIL, INT, 0, 0); r->n_lval = 0; r->n_rval = SP; r = block(PLUS, r, bcon(stacksize), INT, 0, 0); l = block(REG, NIL, NIL, INT, 0, 0); l->n_lval = 0; l->n_rval = SP; r = buildtree(ASSIGN, l, r); p = buildtree(COMOP, p, r); } return p; }
/* * Sort arglist so that register assignments ends up last. */ static int argsort(NODE *p) { NODE *q, *r; int rv = 0; if (p->n_op != CM) { if (p->n_op == ASSIGN && p->n_left->n_op == REG && coptype(p->n_right->n_op) != LTYPE) { q = tempnode(0, p->n_type, p->n_df, p->n_ap); r = ccopy(q); p->n_right = buildtree(COMOP, buildtree(ASSIGN, q, p->n_right), r); } return rv; } if (p->n_right->n_op == CM) { /* fixup for small structs in regs */ q = p->n_right->n_left; p->n_right->n_left = p->n_left; p->n_left = p->n_right; p->n_right = p->n_left->n_right; p->n_left->n_right = q; } if (p->n_right->n_op == ASSIGN && p->n_right->n_left->n_op == REG && coptype(p->n_right->n_right->n_op) != LTYPE) { /* move before everything to avoid reg trashing */ q = tempnode(0, p->n_right->n_type, p->n_right->n_df, p->n_right->n_ap); r = ccopy(q); p->n_right->n_right = buildtree(COMOP, buildtree(ASSIGN, q, p->n_right->n_right), r); } if (p->n_right->n_op == ASSIGN && p->n_right->n_left->n_op == REG) { if (p->n_left->n_op == CM && p->n_left->n_right->n_op == STASG) { q = p->n_left->n_right; p->n_left->n_right = p->n_right; p->n_right = q; rv = 1; } else if (p->n_left->n_op == STASG) { q = p->n_left; p->n_left = p->n_right; p->n_right = q; rv = 1; } } return rv | argsort(p->n_left); }
void buildtree(int rs,int l,int r) { tree[rs].l=l; tree[rs].r=r; if(l==r) { tree[rs].s=a[l]; return ; } int mid=(l+r)/2; buildtree(rs*2,l,mid); buildtree(rs*2+1,mid+1,r); tree[rs].s=max(tree[rs*2].s,tree[rs*2+1].s); }
/* * The "initial exec" tls model. */ static NODE * tlsinitialexec(NODE *p) { NODE *q, *r, *s; char *s1, *s2; /* * movq %fs:0,%rax * addq x@GOTTPOFF(%rip),%rax */ q = bcon(0); q->n_type = STRTY; s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap)); r = mkx("=r", r); r = block(XASM, r, q, INT, 0, 0); s1 = "movq %%fs:0,%0\n\taddq "; s2 = "@GOTTPOFF(%%rip),%0"; if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) { p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1)); p->n_sp->sap->sarg(0) = p->n_sp->sname; } r->n_name = mk3str(s1, attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2); r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap); r = buildtree(UMUL, r, NIL); tfree(p); return r; }
static NODE * builtin_isany(NODE *a, TWORD rt, int cmpt) { NODE *p, *q; TWORD t; if ((t = mtcheck(a)) == 0) return bcon(0); p = buildtree(OROR, mtisnan(a->n_left), mtisnan(a->n_right)); p = buildtree(NOT, p, NIL); q = buildtree(cmpt, cast(ccopy(a->n_left), t, 0), cast(ccopy(a->n_right), t, 0)); p = buildtree(ANDAND, p, q); tfree(a); return p; }
int main() { int t, i, j, n, sr, steps; Treap[0].l = Treap[0].r = Treap[0].key = 0; scanf("%d", &t); while (t--) { // memset(Treap,0,MAXNODES*sizeof(item)); scanf("%d", &n); buildtree(1, 1, n, 0); i = n; j = 2; steps = 2; a[1] = a[2] = 1; while (i > 1) { //printf("\n\ncall erase with j=%d steps:%d\n",j,steps); erase_key(1, j, steps - 1); // print_tree(1); i--; steps++; j = ((j + steps - 2) % i) + 1; } a[2] = 1; sr = search_key(1); a[Treap[sr].idx] = steps - 1; for (i = 1; i <= n; i++) printf("%d ", a[i]); printf("\n"); //n==2?printf("2\n"):printf("%d\n",Treap[sr].idx); // (Treap[1].l)? printf("%d\n",Treap[1].idx):printf("%d\n",Treap[1].idx); } return 0; }
int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", a + i); } for (int i = 1; i <= m; i++) { scanf("%d", w + i); } for (int i = 1; i <= n; i++) { p[i] = hash[a[i]]; hash[a[i]] = i; } std::fill(hash + 1, hash + m + 1, 0); for (int i = n; i >= 1; i--) { value[i] = value[i + 1]; if (hash[a[i]] == 0) value[i] += w[a[i]]; else if (hash[a[i]] == 1) value[i] -= w[a[i]]; hash[a[i]]++; } buildtree(1, 1, n); long long answer = -INF; for (int i = n; i >= 1; i--) { answer = std::max(answer, query(1, 1, n, 1, i)); modify(1, 1, n, p[i] + 1, i - 1, -w[a[i]]); modify(1, 1, n, p[p[i]] + 1, p[i], w[a[i]]); } std::cout << answer << std::endl; return 0; }