比赛 |
防止浮躁的小练习v0.4 |
评测结果 |
WWAWWWWWWW |
题目名称 |
走出金字塔 |
最终得分 |
10 |
用户昵称 |
sxysxy |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2016-10-13 20:14:17 |
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <vector>
#include <queue>
#include <list>
#include <string>
#include <ext/pb_ds/priority_queue.hpp>
#include <deque>
#include <set>
#include <map>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <climits>
#include <functional>
#include <cctype>
using namespace std;
#define MAXN 2333
class dinic
{
private:
bool vis[MAXN];
int dist[MAXN];
int cure[MAXN];
vector<int> G[MAXN];
struct edge
{
int from, to, rem;
};
int s, t;
vector<edge> edges;
public:
dinic(int fr, int to)
{
s = fr;
t = to;
}
void addedge(int u, int v, int c)
{
edges.push_back((edge){u, v, c});
edges.push_back((edge){v, u, 0});
int k = edges.size();
G[u].push_back(k-2);
G[v].push_back(k-1);
}
bool bfs()
{
memset(vis, 0, sizeof(vis));
queue<int> q;
q.push(s);
vis[s] = true;
dist[s] = 0;
while(q.size())
{
int c = q.front();
q.pop();
for(int i = 0; i < G[c].size(); i++)
{
edge &e = edges[G[c][i]];
if(!vis[e.to] && e.rem > 0)
{
vis[e.to] = true;
dist[e.to] = dist[c] + 1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x, int f)
{
if(f == 0 || x == t)return f;
int tot = 0;
int nt;
for(int &i = cure[x]; i < G[x].size(); i++)
{
edge &e = edges[G[x][i]];
if(dist[e.to] == dist[x] + 1 && (nt = dfs(e.to, min(f, e.rem))) > 0)
{
f -= nt;
tot += nt;
e.rem -= nt;
edges[G[x][i]^1].rem += nt;
if(f == 0)break;
}
}
return tot;
}
int maxf()
{
int f = 0;
while(bfs())
{
memset(cure, 0, sizeof(cure));
f += dfs(s, 0x7fffffff);
}
return f;
}
};
#define MAXM 10001
class MCMF
{
struct edge
{
int from, to;
int rem, cost;
};
int s, t;
int cost[MAXM];
int path[MAXM];
int flow[MAXM];
bool vis[MAXM];
vector<int> G[MAXM];
vector<edge> edges;
public:
MCMF(int a, int b)
{
s = a;
t = b;
}
void addedge(int f, int t, int c, int v)
{
edges.push_back((edge){f, t, c, v});
edges.push_back((edge){t, f, 0, -v});
int k = edges.size();
G[f].push_back(k-2);
G[t].push_back(k-1);
}
bool spfa(int &fl, int &ct)
{
queue<int> q;
memset(vis, false, sizeof(vis));
memset(cost, 0x3f, sizeof(cost));
memset(flow, 0x3f, sizeof(flow));
vis[s] = true;
flow[s] = 0x3f3f3f3f;
cost[s] = 0;
q.push(s);
while(q.size())
{
int c = q.front();
q.pop();
for(int i = 0; i < G[c].size(); i++)
{
edge &e = edges[G[c][i]];
if(e.rem > 0 && cost[e.to] > cost[c] + e.cost)
{
cost[e.to] = cost[c] + e.cost;
path[e.to] = G[c][i];
flow[e.to] = min(flow[c], e.rem);
if(!vis[e.to])
{
q.push(e.to);
vis[e.to] = true;
}
}
}
vis[c] = false;
}
if(cost[t] == 0x3f3f3f3f)return false;
fl += flow[t];
ct += cost[t] * flow[t];
for(int cur = t; cur != s; cur = edges[path[cur]].from)
{
int p = path[cur];
edges[p].rem -= flow[t];
edges[p^1].rem += flow[t];
}
return true;
}
int mcmf(int &c)
{
int f = 0;
c = 0;
while(spfa(f, c));
return f;
}
};
#define NEXT_SIZE 16
typedef struct trieNodeType
{
bool isFinal;
struct trieNodeType *(*next);
}trieNode, *pTrieNode;
typedef struct trieType
{
trieNode *root;
}trie;
void initTrie(trie *t)
{
t -> root = (trieNode *)malloc(sizeof(trieNode));
memset(t -> root, 0, sizeof(trieNode));
}
trieNode *appendChar(trieNode *d, int t)
{
if(!d -> next)
{
d -> next = (pTrieNode *)malloc(sizeof(pTrieNode) * NEXT_SIZE);
memset(d -> next, 0, sizeof(pTrieNode) * NEXT_SIZE);
}
if(!d -> next[t])
{
d -> next[t] = (pTrieNode)malloc(sizeof(trieNode));
memset(d -> next[t], 0, sizeof(trieNode));
}
return d -> next[t];
}
void insertWord(trie *t, char *w, int len)
{
trieNode *fw = t -> root;
for(int i = 0; i < len; i++)
{
unsigned char c = w[i];
unsigned hw = (c & (unsigned char)0xf0)>>4; //高四位
unsigned lw = c & (unsigned char)0x0f; //低四位
fw = appendChar(fw, hw);
fw = appendChar(fw, lw);
}
fw -> isFinal = true;
}
bool existWord(trie *t, char *w, int len)
{
trieNode *fw = t -> root;
for(int i = 0; i < len; i++)
{
if(!fw -> next)
return false;
unsigned char c = w[i];
unsigned hw = (c & (unsigned char)0xf0)>>4;
unsigned lw = c & (unsigned char)0x0f;
if(fw -> next[hw])
fw = fw -> next[hw];
else return false;
if(fw -> next[lw])
fw = fw -> next[lw];
else return false;
if(!fw)return false;
}
return fw -> isFinal;
}
void destroyTrieNodes(pTrieNode d)
{
if(!d)return;
if(!d -> next)return;
for(int i = 0; i < NEXT_SIZE; i++)
if(d -> next[i])destroyTrieNodes(d -> next[i]);
for(int i = 0; i < NEXT_SIZE; i++)
if(d -> next[i])free(d -> next[i]);
free(d -> next);
}
void destroyTrie(trie *t)
{
destroyTrieNodes(t -> root);
}
typedef struct _AVL
{
struct _AVL *left, *right;
int data;
int height;
int size;
}AVLNode, *pNode, *AVLTree;
#define HEIGHT(x) ((x)?(x)->height:-1)
#define SIZE(x) ((x)?(x)->size:0)
void maintain(pNode k)
{
if(k)
{
k -> height = max(HEIGHT(k -> left), HEIGHT(k -> right)) + 1;
k -> size = SIZE(k -> left) + SIZE(k -> right) + 1;
}
}
pNode singleRotateLL(pNode k)
{
pNode k1 = k -> left;
k -> left = k1 -> right;
k1 -> right = k;
maintain(k);
maintain(k1);
return k1;
}
pNode singleRotateRR(pNode k)
{
pNode k1 = k -> right;
k -> right = k1 -> left;
k1 -> left = k;
maintain(k);
maintain(k1);
return k1;
}
pNode doubleRotateLR(pNode k)
{
k -> left = singleRotateRR(k -> left);
return singleRotateLL(k);
}
pNode doubleRotateRL(pNode k)
{
k -> right = singleRotateLL(k -> right);
return singleRotateRR(k);
}
AVLTree insert(AVLTree t, int x)
{
if(!t)
{
t = new AVLNode;
t -> data = x;
t -> size = 1;
t -> left = t -> right = 0;
}else
{
if(x < t -> data)
{
t -> left = insert(t -> left, x);
if(HEIGHT(t -> left) - HEIGHT(t -> right) == 2)
{
if(x < t -> left -> data)
t = singleRotateLL(t);
else
t = doubleRotateLR(t);
}
}else
{
t -> right = insert(t -> right, x);
if(HEIGHT(t -> right) - HEIGHT(t -> left) == 2)
{
if(x >= t -> right -> data)
t = singleRotateRR(t);
else
t = doubleRotateRL(t);
}
}
}
maintain(t);
return t;
}
pNode delBalance(pNode k)
{
if(HEIGHT(k -> right) - HEIGHT(k -> left) == 2)
{
if(k -> right)
{
if(HEIGHT(k -> right -> right) >= HEIGHT(k -> right -> left))
k = singleRotateRR(k);
else
k = doubleRotateRL(k);
}
}
if(HEIGHT(k -> left) - HEIGHT(k -> right) == 2)
{
if(k -> left)
{
if(HEIGHT(k -> left -> left) >= HEIGHT(k -> left -> right))
k = singleRotateLL(k);
else
k = doubleRotateLR(k);
}
}
#define put0 main
maintain(k);
return k;
}
AVLTree delNode(AVLTree t, int x)
{
if(!t)
return NULL;
if(x == t -> data)
{
if(!t -> right)
{
pNode tmp = t;
t = t -> left;
free(tmp);
}else
{
pNode tmp = t -> right;
while(tmp -> left)
tmp = tmp -> left;
t -> data = tmp -> data;
t -> right = delNode(t -> right, t -> data);
}
maintain(t);
return t;
}
if(x < t -> data)
{
t -> left = delNode(t -> left, x);
}else
{
t -> right = delNode(t -> right, x);
}
if(t -> left)
t -> left = delBalance(t -> left);
if(t -> right)
t -> right = delBalance(t -> right);
if(t)
t = delBalance(t);
return t;
}
int Smaller(pNode t, int x)
{
if(!t)return 0;
if(x < t -> data)
return Smaller(t -> left, x);
else
return 1 + SIZE(t -> left) + Smaller(t -> right, x);
}
int last = 0;
struct _SegNode
{
int ls, rs;
AVLTree rt;
int l, r;
}ns[MAXN<<1];
int data[MAXN];
int build(int l, int r)
{
int cur = ++last;
ns[cur].l = l;
ns[cur].r = r;
ns[cur].rt = NULL;
for(int i = l; i <= r; i++)
ns[cur].rt = insert(ns[cur].rt, data[i]);
if(l == r)
return cur;
int mid = (l+r)>>1;
if(l <= mid)
{
ns[cur].ls = build(l, mid);
ns[cur].rs = build(mid+1, r);
}
return cur;
}
int queryTree(int c, int l, int r, int n)
{
if(ns[c].l == l && ns[c].r == r)
return Smaller(ns[c].rt, n);
int ls= ns[c].ls;
int rs = ns[c].rs;
if(r <= ns[ls].r)
return queryTree(ls, l, r, n);
else if(l >= ns[rs].l)
return queryTree(rs, l, r, n);
else
return queryTree(ls, l, ns[ls].r, n) + queryTree(rs, ns[rs].l, r, n);
}
void update(int c, int pos, int v)
{
ns[c].rt = delNode(ns[c].rt, data[pos]);
ns[c].rt = insert(ns[c].rt, v);
int ls = ns[c].ls;
int rs = ns[c].rs;
if(ls && pos >= ns[ls].l && pos <= ns[ls].r)
update(ls, pos, v);
else if(rs && pos >= ns[rs].l && pos <= ns[rs].r)
update(rs, pos, v);
}
void change(int pos, int v)
{
update(1, pos, v);
data[pos] = v;
}
int solve(int l, int r, int k)
{
int x = 0;
int y = 0x7fffffff;
int ans = 0;
while(x <= y)
{
int mid = (x+y)>>1;
int f = queryTree(1, l, r, mid);
if(f >= k)
{
y = mid-1;
ans = mid;
}
else
x = mid+1;
}
return ans;
}
#include <cstdio>
#include <cstring>
using namespace std;
#define ALPHA 26
#define BASE 'a'
class SAM
{
int last, size;
public:
struct state
{
int len, link;
int next[ALPHA];
int fast, fast_len;
bool mark;
void init()
{
len = fast = fast_len = 0;
link = -1;
mark = false;
memset(next, 0, sizeof(next));
}
}st[MAXN << 1];
int newst()
{
st[size++].init();
return size-1;
}
SAM()
{
last = size = 0;
newst();
}
void expand(int c)
{
int cur = newst();
st[cur].len = st[last].len + 1;
int p;
for(p = last; p != -1 && !st[p].next[c]; p = st[p].link)
st[p].next[c] = cur;
if(p == -1)st[cur].link = 0;
else
{
int q = st[p].next[c];
if(st[q].len == st[p].len + 1)st[cur].link = q;
else
{
int clone = newst();
st[clone].len = st[p].len+1;
st[clone].link = st[q].link;
memcpy(st[clone].next, st[q].next, sizeof(st[clone].next));
for(; p != -1 && st[p].next[c] == q; p = st[p].link)
st[p].next[c] = clone;
st[q].link = st[cur].link = clone;
}
}
last = cur;
}
void mark_suffix()
{
for(int p = last; p != -1; p = st[p].link)
st[p].mark = true;
}
void calc_fast()
{
for(int p = 0; p < size; p++)
{
int q, f = 0;
for(int i = 0; i < ALPHA; i++)
{
if(st[p].next[i])
{
f++;
q = st[p].next[i];
}
}
if(f == 1 && !st[p].mark)
{
st[p].fast = q;
st[p].fast_len = 1;
}
}
}
int fast_go(int s)
{
int p, sum = 0;
for(p = s; st[p].fast; p = st[p].fast)
sum += st[p].fast_len;
for(int q = s; st[q].fast; q = st[q].fast)
{
sum -= st[q].fast_len;
st[q].fast = p;
st[q].fast_len += sum;
}
return p;
}
int top;
int *psa;
void dfs(int u, int d)
{
if(st[u].mark)psa[top++] = d;
for(int i = 0; i < ALPHA; i++)
{
if(st[u].next[i])
{
state &go = st[st[u].next[i]];
fast_go(st[u].next[i]);
if(go.fast)
dfs(go.fast, d-1-go.fast_len);
else
dfs(st[u].next[i], d-1);
}
}
}
void buildSA(int len, int *buf)
{
mark_suffix();
calc_fast();
top = 0;
psa = buf;
dfs(0, len);
}
}sam;
int f(){freopen("ha14c.in", "r", stdin);freopen("ha14c.out", "w", stdout);}
int sa[MAXN];
char buf[MAXN];
int height[MAXN];
int rank[MAXN];
void calc_height(int n)
{
char *p = buf-1;
for(int i = 1; i <= n; i++)
rank[sa[i]] = i;
int k = 0;
for(int i = 1; i <= n; i++)
{
if(k)k--;
int j = sa[rank[i]-1];
while(p[i+k] == p[j+k])k++;
height[rank[i]] = k;
}
}
int put0(){puts("0");}
class Bignum
{
void mknum(const char *s, int len = -1)
{
sign = 0;
if(*s == '-')
{
mknum(s+1);
sign = 1;
return;
}
int l;
if(len == -1)
l = strlen(s);
else
l = len;
l = strlen(s);
bits.clear();
bits.resize(l);
for(int i = l-1; i >= 0; i--)
bits[l-i-1] = s[i] - '0';
maintain();
}
void mknum(string &s)
{
mknum(s.c_str(), s.length());
}
void us_addto(Bignum &b)
{
int mlen = max(b.bits.size(), bits.size());
int slen = bits.size();
int olen = b.bits.size();
bits.resize(mlen);
for(int i = 0; i < mlen; i++)
{
int s = 0;
if(i < slen)s += bits[i];
if(i < olen)s += b.bits[i];
bits[i] = s;
}
maintain();
}
class FFTer
{
class Complex
{
public:
double real, image;
Complex(double a = 0, double b = 0)
{
real = a;
image = b;
}
Complex operator + (const Complex &o){return Complex(real+o.real, image+o.image);}
Complex operator - (const Complex &o){return Complex(real-o.real, image-o.image);}
Complex operator * (const Complex &o){return Complex(real*o.real-image*o.image, real*o.image+o.real*image);}
Complex operator * (double k){return Complex(real*k, image*k);}
Complex operator / (double k){return Complex(real/k, image/k);}
};
public:
vector<Complex> a;
int n;
FFTer(vector<int> &vec)
{
a.resize(vec.size());
for(int i = 0; i < vec.size(); i++)
a[i].real = vec[i];
n = vec.size();
}
void transform()
{
int j = 0;
int k;
for(int i = 0; i < n; i++)
{
if(j > i)swap(a[i], a[j]);
k = n;
while(j & (k >>= 1))j &= ~k;
j |= k;
}
}
void FFT(bool IDFT = false)
{
const double Pi = IDFT?-acos(-1.0):acos(-1.0);
transform();
for(int s = 1; s < n; s <<= 1)
{
for(int t = 0; t < n; t += s<<1)
{
double x = Pi/s;
Complex omgn(cos(x), sin(x));
Complex omg(1.0, 0.0);
for(int m = 0; m < s; m++)
{
int a1 = m+t;
int a2 = m+t+s;
Complex comm = omg * a[a2];
a[a2] = a[a1] - comm;
a[a1] = a[a1] + comm;
omg = omg * omgn;
}
}
}
if(IDFT)
for(int i = 0; i < n; i++)
a[i] = a[i] / n;
}
void mul(FFTer &o)
{
int s = 1;
while(s < n + o.n)s <<= 1;
n = o.n = s;
a.resize(s);
o.a.resize(s);
FFT(false);
o.FFT(false);
for(int i = 0; i < n; i++)
a[i] = a[i] * o.a[i];
FFT(true);
}
};
void us_multo(Bignum &b)
{
FFTer x(bits);
FFTer y(b.bits);
x.mul(y);
bits.clear();
bits.resize(x.a.size());
for(int i = 0; i < x.n; i++)
bits[i] = (int)(x.a[i].real+0.5);
maintain();
}
void us_multo_simu(Bignum &b)
{
vector<int> r;
r.resize(max(length(),b.length())<<1);
for(int i = 0; i < length(); i++)
for(int j = 0; j < b.length(); j++)
r[i+j] += bits[i] * b.bits[j];
*(&(this -> bits)) = r;
maintain();
}
void us_subto(Bignum &b)
{
int mlen = length();
int olen = b.length();
for(int i = 0; i < mlen; i++)
{
int s = bits[i];
if(i < olen)s -= b.bits[i];
bits[i] = s;
if(bits[i] < 0)
{
bits[i] += 10;
bits[i+1] -= 1;
}
}
for(int i = bits.size() - 1; !bits[i] && i >= 1; i--)bits.pop_back();
if(bits.size() == 1 && bits[0] == 0)sign = 0;
}
void us_divto(Bignum &b)
{
if(length() == 1 && bits[0] == 0)return;
Bignum L("0");
L.sign = 0;
Bignum R(*this);
R.sign = 0;
Bignum two("2");
R *= two;
Bignum one("1");
one.sign = 0;
while(L + one != R)
{
Bignum M = L+R;
M.divto2();
Bignum t = M*b;
if(t > *this)
{
R = M;
}else if(t < *this)
{
L = M;
}else
{
*this = M;
L = M;
break;
}
}
*this = L;
}
public:
int sign;
vector<int> bits;
int length()
{
return bits.size();
}
void maintain()
{
for(int i = 0; i < bits.size(); i++)
{
if(i + 1 < bits.size())
bits[i+1] += bits[i]/10;
else if(bits[i] > 9)
bits.push_back(bits[i]/10);
bits[i] %= 10;
}
if(bits.size() == 0)
{
bits.push_back(0);
sign = 0;
}
for(int i = bits.size() - 1; !bits[i] && i >= 1; i--)bits.pop_back();
}
Bignum(string &s)
{
Bignum();
mknum(s);
}
Bignum(const char *s)
{
Bignum();
mknum(s);
}
Bignum(int n)
{
Bignum();
char buf[15];
sprintf(buf, "%d", n);
mknum(buf);
}
Bignum()
{
sign = 0;
bits.push_back(0);
}
Bignum(const Bignum& b)
{
copy(b);
}
void copy(const Bignum& b)
{
sign = b.sign;
bits = b.bits;
}
bool us_cmp(Bignum &b)
{
if(length() != b.length())return false;
int l = length();
for(int i = 0; i < l; i++)
if(bits[i] != b.bits[i])
return false;
return true;
}
bool us_larger(Bignum &b)
{
if(length() > b.length())return true;
else if(length() < b.length())return false;
int l = length();
for(int i = l-1; i >= 0; i--)
if(bits[i] > b.bits[i])
return true;
else if(bits[i] < b.bits[i])
return false;
return false;
}
bool operator== (Bignum &o)
{
if(sign != o.sign)
return false;
return us_cmp(o);
}
bool operator!= (Bignum &o)
{
return !(*this == o);
}
bool operator> (Bignum &o)
{
if(sign == 0 && o.sign == 1)return true;
if(sign == 1 && o.sign == 0)return false;
if(sign == o.sign && sign)return !us_larger(o);
return us_larger(o);
}
bool operator< (Bignum &o)
{
return !(*this == o || *this > o);
}
bool operator<= (Bignum &o)
{
return *this < o || *this == o;
}
bool operator>= (Bignum &o)
{
return *this > o || *this == o;
}
// -------------------------------
Bignum& operator+= (Bignum &o)
{
if(!sign && !o.sign)
{
us_addto(o);
sign = 0;
}
else if(sign && o.sign)
{
us_addto(o);
sign = 1;
}
else if(sign && !o.sign)
{
if(o.us_larger(*this))
{
Bignum t(o);
t.us_subto(*this);
*this = t;
sign = 0;
}else
{
us_subto(o);
sign = 1;
if(bits.size() == 1 && bits[0] == 0)sign = 0;
}
}else if(!sign && o.sign)
{
if(us_larger(o))
{
us_subto(o);
sign = 0;
}else
{
Bignum t(o);
t.us_subto(*this);
*this = t;
sign = 1;
if(bits.size() == 1 && bits[0] == 0)sign = 0;
}
}
return *this;
}
Bignum operator+ (Bignum &o)
{
Bignum t(*this);
t += o;
return t;
}
Bignum& operator*= (Bignum &o)
{
if(length() + o.length() > 800)
us_multo(o);
else
us_multo_simu(o);
if(sign == o.sign)sign = 0;
else sign = 1;
return *this;
}
Bignum operator* (Bignum &o)
{
Bignum t(*this);
t *= o;
return t;
}
Bignum& operator-= (Bignum &o)
{
if(!sign && !o.sign)
{
if(us_larger(o))
{
us_subto(o);
sign = 0;
}
else
{
Bignum t(o);
t.us_subto(*this);
*this = t;
sign = 1;
if(bits.size() == 1 && bits[0] == 0)sign = 0;
}
}else if(sign && o.sign)
{
if(us_larger(o))
{
us_subto(o);
sign = 1;
if(bits.size() == 1 && bits[0] == 0)sign = 0;
}else
{
Bignum t(o);
t.us_subto(*this);
*this = t;
sign = 0;
}
}else if(!sign && o.sign)
{
us_addto(o);
sign = 0;
}else if(sign && !o.sign)
{
us_addto(o);
sign = 1;
}
return *this;
}
Bignum operator- (Bignum &o)
{
Bignum t(*this);
t -= o;
return t;
}
Bignum& divto2()
{
if(!bits.size())return *this;
bits[0] >>= 1;
int i;
for(i = 1; i < bits.size(); i++)
{
if(bits[i] & 1)bits[i-1] += 5;
bits[i] >>= 1;
}
if(bits[i-1] == 0)bits.pop_back();
return *this;
}
Bignum& operator/= (Bignum &o)
{
us_divto(o);
if(sign == o.sign)sign = 0;
else sign = 1;
return *this;
}
Bignum operator/ (Bignum &o)
{
Bignum t(*this);
t /= o;
return t;
}
Bignum abs()
{
Bignum t(*this);
t.sign = 0;
return t;
}
Bignum sqrt()
{
Bignum L("0"), R(*this);
Bignum one("1");
Bignum m, t;
while(L + one != R)
{
m = L+R;
m.divto2();
Bignum t = m*m;
if(t == *this)return m;
else if(t > *this)R = m;
else L = m;
}
return L;
}
Bignum pow(Bignum &e)
{
if(e.sign)return 1;
Bignum ans("1");
Bignum base(*this);
Bignum zero("0");
Bignum exp(e);
while(exp > zero)
{
if(exp.bits[0] & 1)
{
ans *= base;
}
base *= base;
exp.divto2();
}
if(sign && e.bits[0] & 1)ans.sign = 1;
return ans;
}
Bignum log(Bignum &base)
{
if(sign)return 0;
if(length() == 1 && bits[0] == 1)return 0;
if(*this <= base)return 1;
Bignum one("1");
Bignum r("1");
Bignum c("0");
while(r < *this)
{
r *= base;
c += one;
}
if(r != *this)c -= one;
return c;
}
Bignum lg()
{
Bignum ten("10");
return log(ten);
}
Bignum factorial()
{
Bignum r("1");
Bignum zero("0");
Bignum one("1");
Bignum t(*this);
while(t > zero)
{
r *= t;
t -= one;
}
return r;
}
// -----------------------------------
friend istream& operator>>(istream &is, Bignum &b)
{
string s;
is >> s;
b.mknum(s);
return is;
}
friend ostream& operator<<(ostream &os, Bignum b)
{
if(b.sign)os << '-';
for(int i = b.bits.size()-1; i >= 0; i--)os << b.bits[i];
return os;
}
string to_string()
{
int sz = length();
string s;
if(sign)
s.resize(sz+1);
else
s.resize(sz);
int i = 0;
if(sign)s[i++] = '-';
for(int j = sz-1; i < sz+sign; i++, j--)
s[i] = bits[j] + '0';
return s;
}
};
const int MOD = (479<<21)+1;
const int G = 3;
typedef long long LL;
LL quick_pow(LL a, LL b)
{
LL res = 1;
LL base = a%MOD;
while(b)
{
if(b & 1)
{
res *= base;
res %= MOD;
}
b >>= 1;
base *= base;
base %= MOD;
}
return res;
}
LL omg[MAXM+1];
void calcOmg()
{
for(int i = 0; i <= MAXM; i++)
{
int k = 1 << i;
omg[i] = quick_pow(G, (MOD-1)/k);
}
}
class NTTer
{
public:
LL a[MAXN];
LL len;
void trans()
{
int j = len >> 1;
for(int i = 1; i < len-1; i++)
{
if(i < j)swap(a[i], a[j]);
int k = len >> 1;
while(j >= k)
{
j -= k;
k >>= 1;
}
if(j < k)j += k;
}
}
void NTT(bool DNTT = false)
{
trans();
int id = 0;
for(int h = 2; h <= len; h <<= 1)
{
id++;
for(int j = 0; j < len; j += h)
{
LL omgn = 1;
for(int k = j; k < j + h/2; k++)
{
LL u = a[k] % MOD;
LL t = omgn * a[k + h/2] % MOD;
a[k] = (u+t)%MOD;
a[k+h/2] = (u-t+MOD)%MOD;
omgn = omgn*omg[id]%MOD;
}
}
}
if(DNTT)
{
for(int i = 1; i < len/2; i++)
swap(a[i], a[len-i]);
LL inv = quick_pow(len, MOD-2);
for(int i = 0; i < len; i++)
a[i] = a[i] * inv % MOD;
}
}
void mul(NTTer &o)
{
int s = 1;
while(s < len+o.len) s<<=1;
len = o.len = s;
NTT(false);
o.NTT(false);
for(int i = 0; i < len; i++)
a[i] = a[i]*o.a[i]%MOD;
NTT(true);
}
};
bool vis[MAXN];
int primes[MAXN];
int miu[MAXN];
int k = f();
int calc(int limit)
{
memset(vis, false, sizeof(vis));
memset(miu, 0, sizeof(miu));
int tot = 0;
miu[1] = 1;
for(int i = 2; i <= limit; i++)
{
if(!vis[i])
{
primes[tot++] = i;
miu[i] = -1;
}
for(int j = 0; j < tot; j++)
{
int k = i*primes[j];
if(k > limit)break;
vis[k] = true;
if(i % primes[j])
miu[k] = -miu[i];
else
break;
}
}
}