ACdream Andrew Stankevich's Contest(1)
来源:互联网 发布:windows安装淘宝镜像 编辑:程序博客网 时间:2024/05/25 21:34
国庆打了场组队 效果还不错 季军 现在发下题解
A:
高精度模拟即可 与n互素的数不会离n/2太远 直接暴力
代码:
#include<stdio.h>#include<string>#include<string.h>#include<iostream>using namespace std; //compare比较函数:相等返回0,大于返回1,小于返回-1int compare(string str1, string str2) { if (str1.length() > str2.length()) return 1; else if (str1.length() < str2.length()) return -1; else return str1.compare(str2);}//高精度加法//只能是两个正数相加string add(string str1, string str2) //高精度加法 { string str; int len1 = str1.length(); int len2 = str2.length(); //前面补0,弄成长度相同 if (len1 < len2) { for (int i = 1; i <= len2 - len1; i++) str1 = "0" + str1; } else { for (int i = 1; i <= len1 - len2; i++) str2 = "0" + str2; } len1 = str1.length(); int cf = 0; int temp; for (int i = len1 - 1; i >= 0; i--) { temp = str1[i] - '0' + str2[i] - '0' + cf; cf = temp / 10; temp %= 10; str = char(temp + '0') + str; } if (cf != 0) str = char(cf + '0') + str; return str;}//高精度减法//只能是两个正数相减,而且要大减小string sub(string str1, string str2) //高精度减法 { string str; int tmp = str1.length() - str2.length(); int cf = 0; for (int i = str2.length() - 1; i >= 0; i--) { if (str1[tmp + i] < str2[i] + cf) { str = char(str1[tmp + i] - str2[i] - cf + '0' + 10) + str; cf = 1; } else { str = char(str1[tmp + i] - str2[i] - cf + '0') + str; cf = 0; } } for (int i = tmp - 1; i >= 0; i--) { if (str1[i] - cf >= '0') { str = char(str1[i] - cf) + str; cf = 0; } else { str = char(str1[i] - cf + 10) + str; cf = 1; } } str.erase(0, str.find_first_not_of('0')); //去除结果中多余的前导0 return str;}//高精度乘法//只能是两个正数相乘string mul(string str1, string str2) { string str; int len1 = str1.length(); int len2 = str2.length(); string tempstr; for (int i = len2 - 1; i >= 0; i--) { tempstr = ""; int temp = str2[i] - '0'; int t = 0; int cf = 0; if (temp != 0) { for (int j = 1; j <= len2 - 1 - i; j++) tempstr += "0"; for (int j = len1 - 1; j >= 0; j--) { t = (temp * (str1[j] - '0') + cf) % 10; cf = (temp * (str1[j] - '0') + cf) / 10; tempstr = char(t + '0') + tempstr; } if (cf != 0) tempstr = char(cf + '0') + tempstr; } str = add(str, tempstr); } str.erase(0, str.find_first_not_of('0')); return str;} //高精度除法//两个正数相除,商为quotient,余数为residue//需要高精度减法和乘法void div(string str1, string str2, string "ient, string &residue) { quotient = residue = ""; //清空 if (str2 == "0") //判断除数是否为0 { quotient = residue = "ERROR"; return; } if (str1 == "0") //判断被除数是否为0 { quotient = residue = "0"; return; } int res = compare(str1, str2); if (res < 0) { quotient = "0"; residue = str1; return; } else if (res == 0) { quotient = "1"; residue = "0"; return; } else { int len1 = str1.length(); int len2 = str2.length(); string tempstr; tempstr.append(str1, 0, len2 - 1); for (int i = len2 - 1; i < len1; i++) { tempstr = tempstr + str1[i]; tempstr.erase(0, tempstr.find_first_not_of('0')); if (tempstr.empty()) tempstr = "0"; for (char ch = '9'; ch >= '0'; ch--) //试商 { string str, tmp; str = str + ch; tmp = mul(str2, str); if (compare(tmp, tempstr) <= 0) //试商成功 { quotient = quotient + ch; tempstr = sub(tempstr, tmp); break; } } } residue = tempstr; } quotient.erase(0, quotient.find_first_not_of('0')); if (quotient.empty()) quotient = "0";} string gcd(string a, string b) { if (b.empty()) return a; string s, y; div(a, b, s, y); //cout<<a<<" "<<b<<" "<<s<<" "<<y<<endl; return gcd(b, y);} int main() { ios::sync_with_stdio(false); string n, f1, f2; while (cin >> n) { div(n, "2", f1, f2); while (1) { if (gcd(n, f1) == "1") break; f1 = sub(f1, "1"); } cout << f1 << endl; } return 0;}
B:
上下界无源无汇网络流 不能再模版了…
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<cassert>#include<vector>#include<set>#include<map>#include<queue>using namespace std;const int MAX = 100005;const int INF = 1000000000; struct EDGE { int v, c, next;} edge[1000000];int E, head[MAX];int gap[MAX], cur[MAX];int pre[MAX], dis[MAX];int in[225], low[50000]; void add_edge(int s, int t, int c, int cc) { edge[E].v = t; edge[E].c = c; edge[E].next = head[s]; head[s] = E++; edge[E].v = s; edge[E].c = cc; edge[E].next = head[t]; head[t] = E++;} int min(int a, int b) { return (a == -1 || b < a) ? b : a;} int SAP(int s, int t, int n) { memset(gap, 0, sizeof(gap)); memset(dis, 0, sizeof(dis)); int i; for (i = 0; i < n; i++) cur[i] = head[i]; int u = pre[s] = s, maxflow = 0, aug = -1, v; gap[0] = n; while (dis[s] < n) { loop: for (i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].v; if (edge[i].c > 0 && dis[u] == dis[v] + 1) { aug = min(aug, edge[i].c); pre[v] = u; cur[u] = i; u = v; if (u == t) { for (u = pre[u]; v != s; v = u, u = pre[u]) { edge[cur[u]].c -= aug; edge[cur[u] ^ 1].c += aug; } maxflow += aug; aug = -1; } goto loop; } } int mindis = n; for (i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if (edge[i].c > 0 && dis[v] < mindis) { cur[u] = i; mindis = dis[v]; } } if ((--gap[dis[u]]) == 0) break; gap[dis[u] = mindis + 1]++; u = pre[u]; } return maxflow;} bool solve(int n) { for (int i = 1; i <= n; i++) { if (in[i] > 0) add_edge(0, i, in[i], 0); if (in[i] < 0) add_edge(i, n + 1, -in[i], 0); } SAP(0, n + 1, n + 2); for (int i = head[0]; i != -1; i = edge[i].next) //从源点出发的边都满流 { if (edge[i].c) return false; } return true;} int main() { int n, m, a, b, c; while (~scanf("%d%d", &n, &m)) { E = 0; memset(head, -1, sizeof(head)); memset(in, 0, sizeof(in)); for (int i = 0; i < m; i++) { scanf("%d%d%d%d", &a, &b, &low[i], &c); in[a] -= low[i], in[b] += low[i]; add_edge(a, b, c - low[i], 0); } if (solve(n)) { printf("YES\n"); for (int i = 0; i < m; i++) printf("%d\n", edge[(i << 1) ^ 1].c + low[i]); //反向的流即自由流,再加上下界的流 } else printf("NO\n"); } return 0;}
C:
题可以转化为树上选尽量多的边 选出的边之间没有公共点
树形dp可解
我用dp[i][0.1]表示i这个点的子树的最大值 1表示i点与子树中的点匹配了 0表示没有 我用dp[i][2]表示dp[i][0.1]中的大者 那么转移方程可以很容易的写出
dp[i][0] = sum(dp[v][2]) 其中v表示i的儿子 dp[i][1] = sum(dp[v][2]) - dp[v][2] + dp[v][0] + 1那么这时i和v匹配了
dp的同时记录匹配是很容易的 然后倒着推回去 就可以打印方案了
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>#include<cstdlib>#include<ctime>#include<cmath>using namespace std;#define N 500010#define mp(x,y) make_pair(x,y) int n;int dp[N][3], pre[N], ans[N];int head[N], tot;struct edge { int v, next;} ed[N];int qu[N];pair<int, int> que[N]; void add(int u, int v) { ed[tot].v = v; ed[tot].next = head[u]; head[u] = tot++;} void bfs() { int l = 1, r = 2, u, i; qu[1] = 1; while (l < r) { u = qu[l++]; for (i = head[u]; ~i; i = ed[i].next) qu[r++] = ed[i].v; }} int main() { int i, j, k, tmp; while (~scanf("%d", &n)) { tot = 0; memset(head, -1, sizeof(head)); memset(dp, 0, sizeof(dp)); memset(pre, 0, sizeof(pre)); memset(ans, 0, sizeof(ans)); for (i = 2; i <= n; i++) { scanf("%d", &j); add(j, i); } bfs(); for (i = n; i >= 1; i--) { k = 0; for (j = head[i]; ~j; j = ed[j].next) k += dp[ed[j].v][2]; dp[i][0] = k; for (j = head[i]; ~j; j = ed[j].next) { int v = ed[j].v; tmp = k - dp[v][2] + dp[v][0] + 1; if (tmp > dp[i][1]) { pre[i] = v; dp[i][1] = tmp; } } dp[i][2] = max(dp[i][0], dp[i][1]); } printf("%d\n", dp[1][2] * 1000); int l = 1, r = 2; pair<int, int> u, v; if (dp[1][2] == dp[1][1]) que[1] = mp(1,1); else que[1] = mp(1,0); while (l < r) { u = que[l++]; for (i = head[u.first]; ~i; i = ed[i].next) { v.first = ed[i].v; if (v.first == pre[u.first] && u.second) v.second = 0; else { if (dp[v.first][2] == dp[v.first][0]) v.second = 0; else v.second = 1; } que[r++] = v; } if (u.second) ans[pre[u.first]] = 1; } for (i = j = 1; i <= n; i++) { if (ans[i]) { if (j) j = 0; else printf(" "); printf("%d", i); } } printf("\n"); return 0; }}
D:
我不知道什么题 队友说先记个数然后求个和… 反正我就这么写了- -b
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>#include<cstdlib>#include<ctime>#include<cmath>using namespace std;typedef long long LL;#define inf ((1U<<31)-1)#define N 10010 int n, m;LL ans;int x[N]; int main() { int i, u, v; while (~scanf("%d%d", &n, &m)) { memset(x, 0, sizeof(x)); ans = 0; for (i = 1; i <= m; i++) { scanf("%d%d", &u, &v); x[u]++; x[v]++; } for (i = 1; i <= n; i++) ans += (LL) (x[i]) * x[i]; printf("%lld\n", ans); } return 0;}
E:
一开始以为这题是找循环节 后来发现循环节可能不存在
m很小 所以我们可以利用状压打表 这样形成了一个矩阵 矩阵中(i,j)=1表示能从i状态转到j状态 我们发现这个矩阵是始终不变的 换句话说就是初始状态根据这个矩阵做n次操作 这种事明显可以快速幂来搞 正好前面写过高精度 拿来直接改 1A神马的还是稳稳地 ~~
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>#include<cstdlib>#include<ctime>#include<cmath>using namespace std; string n;int m, p;int k[32][32];int bin[10]; //高精度//compare比较函数:相等返回0,大于返回1,小于返回-1int compare(string str1, string str2) { if (str1.length() > str2.length()) return 1; else if (str1.length() < str2.length()) return -1; else return str1.compare(str2);}//高精度加法//只能是两个正数相加string add(string str1, string str2) //高精度加法 { string str; int len1 = str1.length(); int len2 = str2.length(); //前面补0,弄成长度相同 if (len1 < len2) { for (int i = 1; i <= len2 - len1; i++) str1 = "0" + str1; } else { for (int i = 1; i <= len1 - len2; i++) str2 = "0" + str2; } len1 = str1.length(); int cf = 0; int temp; for (int i = len1 - 1; i >= 0; i--) { temp = str1[i] - '0' + str2[i] - '0' + cf; cf = temp / 10; temp %= 10; str = char(temp + '0') + str; } if (cf != 0) str = char(cf + '0') + str; return str;}//高精度减法//只能是两个正数相减,而且要大减小string sub(string str1, string str2) //高精度减法 { string str; int tmp = str1.length() - str2.length(); int cf = 0; for (int i = str2.length() - 1; i >= 0; i--) { if (str1[tmp + i] < str2[i] + cf) { str = char(str1[tmp + i] - str2[i] - cf + '0' + 10) + str; cf = 1; } else { str = char(str1[tmp + i] - str2[i] - cf + '0') + str; cf = 0; } } for (int i = tmp - 1; i >= 0; i--) { if (str1[i] - cf >= '0') { str = char(str1[i] - cf) + str; cf = 0; } else { str = char(str1[i] - cf + 10) + str; cf = 1; } } str.erase(0, str.find_first_not_of('0')); //去除结果中多余的前导0 return str;}//高精度乘法//只能是两个正数相乘string mul(string str1, string str2) { string str; int len1 = str1.length(); int len2 = str2.length(); string tempstr; for (int i = len2 - 1; i >= 0; i--) { tempstr = ""; int temp = str2[i] - '0'; int t = 0; int cf = 0; if (temp != 0) { for (int j = 1; j <= len2 - 1 - i; j++) tempstr += "0"; for (int j = len1 - 1; j >= 0; j--) { t = (temp * (str1[j] - '0') + cf) % 10; cf = (temp * (str1[j] - '0') + cf) / 10; tempstr = char(t + '0') + tempstr; } if (cf != 0) tempstr = char(cf + '0') + tempstr; } str = add(str, tempstr); } str.erase(0, str.find_first_not_of('0')); return str;} //高精度除法//两个正数相除,商为quotient,余数为residue//需要高精度减法和乘法void div(string str1, string str2, string "ient, string &residue) { quotient = residue = ""; //清空 if (str2 == "0") //判断除数是否为0 { quotient = residue = "ERROR"; return; } if (str1 == "0") //判断被除数是否为0 { quotient = residue = "0"; return; } int res = compare(str1, str2); if (res < 0) { quotient = "0"; residue = str1; return; } else if (res == 0) { quotient = "1"; residue = "0"; return; } else { int len1 = str1.length(); int len2 = str2.length(); string tempstr; tempstr.append(str1, 0, len2 - 1); for (int i = len2 - 1; i < len1; i++) { tempstr = tempstr + str1[i]; tempstr.erase(0, tempstr.find_first_not_of('0')); if (tempstr.empty()) tempstr = "0"; for (char ch = '9'; ch >= '0'; ch--) //试商 { string str, tmp; str = str + ch; tmp = mul(str2, str); if (compare(tmp, tempstr) <= 0) //试商成功 { quotient = quotient + ch; tempstr = sub(tempstr, tmp); break; } } } residue = tempstr; } quotient.erase(0, quotient.find_first_not_of('0')); if (quotient.empty()) quotient = "0";} //快速幂const int mat_n = 32;void matrix_mul(int a[][mat_n], int b[][mat_n]) { int c[mat_n][mat_n]; int i, j, k; for (i = 0; i < mat_n; i++) { for (j = 0; j < mat_n; j++) { c[i][j] = 0; for (k = 0; k < mat_n; k++) { c[i][j] = (c[i][j] + (a[i][k] * b[k][j]) % p) % p; } } } for (i = 0; i < mat_n; i++) for (j = 0; j < mat_n; j++) a[i][j] = c[i][j];} void matrix_power(int s[][mat_n]) { int ans[mat_n][mat_n]; memset(ans, 0, sizeof(ans)); int i, j; for (i = 0; i < mat_n; i++) ans[i][i] = 1; string sh, yu; while (compare(n, "0") != 0) { div(n, "2", sh, yu); if (yu == "1") matrix_mul(ans, s); n = sh; matrix_mul(s, s); } for (i = 0; i < mat_n; i++) for (j = 0; j < mat_n; j++) s[i][j] = ans[i][j];} int main() { ios::sync_with_stdio(false); int i, j, f, flag; bin[0] = 1; for (f = 1; f < 10; f++) bin[f] = bin[f - 1] << 1; while (cin >> n >> m >> p) { for (i = 0; i < bin[m]; i++) { for (j = 0; j < bin[m]; j++) { flag = 1; for (f = 0; f < m - 1; f++) { if (((i & bin[f]) == (j & bin[f]) && (i & bin[f + 1]) == (j & bin[f + 1]) && ((i & bin[f]) << 1) == (j & bin[f + 1]))) { flag = 0; break; } } k[i][j] = flag; //printf("%d ", flag); } //printf("\n"); } n = sub(n, "1"); matrix_power(k); f = 0; for (i = 0; i < bin[m]; i++) { for (j = 0; j < bin[m]; j++) f += k[i][j]; } printf("%d\n", f % p); } return 0;}
F:
唯一一道没做出的题 题解看这http://www.cppblog.com/Yuan/archive/2010/05/02/114163.html
当时我们的思路就卡在“将视角当作边权”这里 这个想法很是巧妙
G:
我犯二的题 我一开始想 按照不讨厌来建边 然后最大团就是答案 但是点这么多… 这时队友说 “简单的二维不降子序列题”… 这才顿悟… 不讨厌就是S和B都大 那么不就是标准的模型了…
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std; int dp[100010],mark[100010],cnt[100010];const int inf=1e9; struct node{ int x,y,idx; bool operator < (const node &a) const{ return x<a.x||(x==a.x&&y>a.y); }}p[100010]; int main(){ int n,t,x,y,ans; int i; while(scanf("%d",&n)!=EOF) { ans=0; //printf("n.%d\n",n); for(i=0;i<n;i++){ scanf("%d%d",&x,&y); //printf("u.........%d\n",i); p[i].x=x; p[i].y=y; p[i].idx=i+1; } sort(p,p+n); for(i=0;i<n;i++) dp[i]=inf; for(i=0;i<n;i++){ int tmp=lower_bound(dp,dp+n,p[i].y)-dp; dp[tmp]=p[i].y; mark[i]=tmp; ans=max(ans,tmp); } printf("%d\n",ans+1); int tot=0; for(i=n-1;i>=0;i--){ if(mark[i]==ans){ cnt[tot++]=p[i].idx; ans--; } } sort(cnt,cnt+tot); for(i=0;i<tot;i++) { printf("%d",cnt[i]); if(i==tot-1) printf("\n"); else printf(" "); } } return 0;}
H:
不知道题… 队友直接就给A了… 我就贴代码吧 - -b
#include<stdio.h>#include<algorithm>#include<iostream>#include<string.h>#include<math.h>using namespace std;typedef long long ll;const int MAXN = 110;#define MAX 2010#define mod 10000#define baselen 4#define in(a) scanf("%d",&a)#define out1(a) printf("%d",a)#define out2(a) printf("%04d",a)int a[MAXN][MAXN]; //增广矩阵int x[MAXN]; //解集bool free_x[MAXN]; //标记是否是不确定的变元inline int abs(int a) { return a > 0 ? a : -a;}void Debug(int equ, int var) { int i, j; for (i = 0; i < equ; i++) { for (j = 0; j < var + 1; j++) { cout << a[i][j] << " "; } cout << endl; } cout << endl;}//m个方程,n个变量!!int rank(int A[MAXN][MAXN], int m, int n) //求解01模2方程的秩!! { int i = 0, j = 0, k, r, u; while (i < m && j < n) //当前正在处理第i行,第j个变量!! { r = i; for (k = i; k < m; k++) if (A[k][j]) { r = k; break; } if (A[r][j]) { if (r != i) for (k = 0; k <= n; k++) swap(A[r][k], A[i][k]); for (u = i + 1; u < m; u++) if (A[u][j]) for (k = i; k <= n; k++) A[u][k] ^= A[i][k]; i++; } j++; } return i; //系数矩阵的秩!}int p[1000], flag[1000], cnt = 0;void get_prime() { int i, j; for (i = 2; i < 600; i++) { if (!flag[i]) p[cnt++] = i; ; for (j = 0; j < cnt && p[j] * i < 600; j++) { flag[i * p[j]] = 1; if (i % p[j] == 0) break; } }}int b[200]; typedef int type;/////////////////////////////////////struct bint { type dig[MAX], len; bint() { len = 0, dig[0] = 0; }};//////////////////////////////////////////////常用函数//(1)void add(bint a, bint b, bint& c) { type i, carry; for (i = carry = 0; i <= a.len || i <= b.len || carry; i++) { if (i <= a.len) carry += a.dig[i]; if (i <= b.len) carry += b.dig[i]; c.dig[i] = carry % mod; carry /= mod; } c.len = i - 1;}//(2)void add(bint a, type b, bint& c) { type i; for (i = 0; i <= a.len || b; i++) { if (i <= a.len) b += a.dig[i]; c.dig[i] = b % mod; b /= mod; } c.len = i - 1;}//(3)void by(bint a, type b, bint& c) { type i, carry; for (i = carry = 0; i <= a.len || carry; i++) { if (i <= a.len) carry += b * a.dig[i]; c.dig[i] = carry % mod; carry /= mod; } i--; while (i && !c.dig[i]) i--; c.len = i;}//(4)void by(bint a, bint b, bint& c) { type i, j, carry; for (i = a.len + b.len + 1; i >= 0; i--) c.dig[i] = 0; for (i = 0; i <= a.len; i++) { carry = 0; for (j = 0; j <= b.len || carry; j++) { carry += c.dig[i + j]; if (j <= b.len) carry += a.dig[i] * b.dig[j]; c.dig[i + j] = carry % mod; carry /= mod; } } i = a.len + b.len + 1; while (i && c.dig[i] == 0) i--; c.len = i;}//(5)void div(bint a, type b, bint& c, type& d) { type i; for (i = a.len, d = 0; i >= 0; i--) { d = d * mod + a.dig[i]; c.dig[i] = d / b; d = d % b; } i = a.len; while (i && c.dig[i] == 0) i--; c.len = i;}//(6)bool input(bint& a) { type i, j, w, k, p; char data[MAX * baselen + 1]; if (scanf("%s", data) == EOF) return false; w = strlen(data) - 1, a.len = 0; for (p = 0; p <= w && data[p] == '0'; p++) ; while (1) { i = j = 0, k = 1; while (i < baselen && w >= p) { j = j + (data[w--] - '0') * k; k *= 10, i++; } a.dig[a.len++] = j; if (w < p) break; } a.len--; return true;}//(7)void output(bint& a) { type i; i = a.len - 1; out1(a.dig[a.len]); while (i >= 0) out2(a.dig[i--]); printf("\n");}//////////////////////////////////////////////////////////////////////////少用函数//(8)void move(bint& a) { type carry, k, t; k = a.len + 1, carry = 0; while (k--) { t = a.dig[k] & 1; a.dig[k] = (a.dig[k] >> 1); if (carry) a.dig[k] += (mod >> 1); carry = t; } if (a.len && a.dig[a.len] == 0) a.len--;}//(9)void sub(bint a, bint b, bint& c) { type i, carry; for (i = carry = 0; i <= a.len; i++) { c.dig[i] = a.dig[i] - carry; if (i <= b.len) c.dig[i] -= b.dig[i]; if (c.dig[i] < 0) carry = 1, c.dig[i] += mod; else carry = 0; } i--; while (i && c.dig[i] == 0) i--; c.len = i;}//(10)void sub(bint a, type b, bint& c) { type i; for (i = 0; i <= a.len; i++) { c.dig[i] = a.dig[i] - b; if (c.dig[i] < 0) b = 1, c.dig[i] += mod; else b = 0; } i--; while (i && c.dig[i] == 0) i--; c.len = i;}//(11)int cmp(bint a, bint b) { if (a.len < b.len) return -1; if (a.len > b.len) return 1; int i = a.len; while (i && a.dig[i] == b.dig[i]) i--; return a.dig[i] - b.dig[i];}//(12)void give(bint a, bint& b) { int i = 0; while (i <= a.len) { b.dig[i] = a.dig[i]; i++; } b.len = a.len;}//(13)void give(type a, bint& b) { b.dig[0] = a % mod; a /= mod; if (a > 0) b.dig[1] = a, b.len = 1; else b.len = 0;}//(14)void shift(bint& a, type k) { int i; i = a.len + k; while (i >= k) { a.dig[i] = a.dig[i - k]; i--; } while (i >= 0) a.dig[i--] = 0; a.len += k;}//(15)void div(bint a, bint b, bint& c, bint& d) { type x, k; bint temp; give(a, d); c.len = c.dig[0] = 0; while (cmp(d, b) > 0) { k = d.len - b.len; if (d.dig[d.len] > b.dig[b.len]) x = d.dig[d.len] / (b.dig[b.len] + 1); else if (k) k--, x = (d.dig[d.len] * mod + d.dig[d.len - 1]) / (b.dig[b.len] + 1); else break; by(b, x, temp); shift(temp, k); sub(d, temp, d); give(x, temp); shift(temp, k); add(c, temp, c); } if (cmp(d, b) >= 0) sub(d, b, d), add(c, (type) 1, c);}int main() { get_prime(); //for(int i=0;i<=100;i++)printf("%d %d\n",i+1,p[i]); int i, j, t, m; while (~scanf("%d%d", &t, &m)) { int xx; memset(a, 0, sizeof(a)); for (i = 0; i < m; i++) { scanf("%d", &xx); for (j = 0; j < t; j++) while (xx % p[j] == 0) { xx /= p[j]; a[j][i] ^= 1; } } //Debug(maxp+1,n); int r = rank(a, t, m); int y = m - r; if (y < 64) { ll ans = (1LL << y) - 1; printf("%lld\n", ans); continue; } bint tmp, Ans; give(1, Ans); while (y--) { tmp = Ans; by(tmp, 2, Ans); } tmp = Ans; sub(tmp, 1, Ans); output(Ans); } return 0;}
- ACdream Andrew Stankevich's Contest(1)
- ACdream Andrew Stankevich's Contest(1)
- ACdream Andrew Stankevich's Contest (2) 哈夫曼树
- 【ACdream】Andrew Stankevich's Contest (22)
- 【ACdream】Andrew Stankevich's Contest (3)
- 【ACDream】Andrew Stankevich's Contest (23)
- 【ACdream】Andrew Stankevich's Contest (4)
- Andrew Stankevich's Contest (1)
- 【ACdream】Andrew Stankevich Contest (1)
- ZOJ 2313 Andrew Stankevich's Contest #1
- Andrew Stankevich's Contest #1 Solution
- Andrew Stankevich's Contest (21)
- Andrew Stankevich's Contest 23
- Andrew Stankevich's Contest #8 Solution
- Andrew Stankevich's Contest #2 Solution
- Andrew Stankevich's Contest #5 Solution
- Andrew Stankevich's Contest #10 Solution
- Andrew Stankevich's Contest #补题
- 数字字符串转成字母串
- 【ACdream】Andrew Stankevich Contest (1)
- 20141001 【 高精度?/数论--斐波那契数列 】 hdoj 1568 Fibonacci
- Java基础-->Java中的程序流程控制与函数
- STM32 读写保护功能及设置
- ACdream Andrew Stankevich's Contest(1)
- 利用cocos2dx 3.2开发消灭星星(七)关于星星的算法
- 黑马程序员——基础加强(jdk1.5新特性)
- SQL语句详解
- 合并排序——分治策略
- NYOJ 170 网络的可靠性
- MySql数据库的基本操作-修改表-删除约束
- [心情贴 ] 今天终于把数据库和编程语言连接起来了
- 使用ViewPager滑动Activity