首页 > 代码库 > ASC #1

ASC #1

开始套题训练,第一套ASC题目,记住不放过每一题,多独立思考。

Problem A ZOJ 2313 Chinese Girls‘ Amusement 循环节

题意:给定n,为圆环长度,求k <= n/2,从1出发,每次顺时针方向走k步,即1->k+1->2*k+1,直到遇到一个已经走过的点结束,要求最终把所有点访问一遍,最后回到1,使得k尽量大。

代码:

 

Problem B ZOJ 2314 Reactor Cooling 无源汇上下界网络流

题意:经典题,有上下界无源无汇的可行流,对于每条边u->v,上界流量C(u,v),下界流量B(u, v),可以这样构图,建立附加源点S,T对于每条边u->v,在流量图中连一条容量为C(u, v)-B(u, v)的边,同时S->v连容量B(u, v) 的边,u->T连B(u, v) 的边,跑一遍网络流,当从S出发的边满流时,有可行流,原图中每条边流量为相应B(u, v)+最大流图中流量g(u, v).

代码:

  1 #include <bits/stdc++.h>  2 #define pb push_back  3 #define mp make_pair  4   5 #define lson   l, m, rt<<1  6 #define rson   m+1, r, rt<<1|1  7 #define sz(x) ((int)((x).size()))  8 #define pb push_back  9 #define in freopen("solve_in.txt", "r", stdin); 10 #define bug(x) printf("Line : %u >>>>>>\n", (x)); 11 #define inf 0x0f0f0f0f 12 using namespace std; 13 typedef long long LL; 14 typedef map<int, int> MPS; 15 typedef pair<int, int> PII; 16 const int maxn = 222; 17 struct Node { 18     int c, l, id; 19     Node() {} 20     Node(int c, int l, int id):c(c), l(l), id(id) {} 21 }; 22 vector<Node> cap; 23  24  25 struct Edge { 26     int u, v, c; 27     Edge(int u, int v, int c):u(u), v(v), c(c) {} 28 }; 29 struct Max_flow { 30     int n, m; 31     int src, sink; 32     vector<Edge> edges; 33     vector<int> G[maxn]; 34     int Now[maxn], Dfn[maxn], cur[maxn]; 35     void init(int n) { 36         this->n = n; 37         for(int i = 0; i < n; i++) G[i].clear(); 38         edges.clear(); 39     } 40     void add(int u, int v, int c) { 41         edges.pb(Edge(u, v, c)); 42         edges.pb(Edge(v, u, 0)); 43         m = edges.size(); 44         G[u].pb(m-2); 45         G[v].pb(m-1); 46     } 47     int ISAP(int s, int flow) { 48         if(s == sink) 49             return flow; 50         int i, tab = n, vary, now = 0; 51         int p = cur[s]; 52         do { 53             Edge &e = edges[G[s][cur[s]]]; 54             if(e.c > 0) { 55                 if(Dfn[s] == Dfn[e.v]+1) 56                     vary = ISAP(e.v, min(flow-now, e.c)), 57                     now += vary, e.c -= vary, edges[G[s][cur[s]]^1].c += vary; 58                 if(Dfn[src] == n) 59                     return now; 60                 if(e.c > 0) tab = min(tab, Dfn[e.v]); 61                 if(flow == now) 62                     break; 63             } 64             cur[s]++; 65             if(cur[s] == (int)G[s].size()) cur[s] = 0; 66         } while(p != cur[s]); 67         if(now == 0) { 68             if(--Now[Dfn[s]] == 0) 69                 Dfn[src] = n; 70             Now[Dfn[s] = tab+1]++; 71         } 72         return now; 73     } 74     int max_flow(int src, int sink) { 75         this->src =http://www.mamicode.com/ src; 76         this->sink = sink; 77         int flow = 0; 78         memset(Dfn, 0, sizeof Dfn); 79         memset(Now, 0, sizeof Dfn); 80         memset(cur, 0, sizeof cur); 81         Now[0] = n; 82         for(; Dfn[src] < n;) 83             flow += ISAP(src, inf); 84         return flow; 85     } 86 } mc; 87 vector<int> mx; 88  89 int main() { 90      91     int T; 92     for(int t = scanf("%d", &T); t <= T; t++) { 93         int n, m; 94         cap.clear(); 95         mx.clear(); 96  97         scanf("%d%d", &n, &m); 98         mc.init(n+2); 99         int src = http://www.mamicode.com/n, sink = n+1;100 101         for(int i = 1; i <= m; i++) {102             int u, v, c, l;103             scanf("%d%d%d%d", &u, &v, &l, &c);104             u--, v--;105             mc.add(u, v, c-l);106             int tmp = mc.edges.size()-2;107             cap.pb(Node(c, l, tmp));108             mc.add(src, v, l);109             tmp = mc.edges.size()-2;110             mx.pb(tmp);111             mc.add(u, sink, l);112         }113         int flow = mc.max_flow(src, sink);114 ////        cout << flow << endl;115         int ok = 1;116         for(int i = 0; i < (int)mx.size(); i++) {117             int id = mx[i];118             if(mc.edges[id].c) {119                 ok = 0;120                 break;121             }122         }123 124         if(t != 1) puts("");125         if(ok) {126             puts("YES");127             for(int i = 0; i < (int)cap.size(); i++) {128                 Node x = cap[i];129                 int id = x.id;130                 printf("%d\n", x.c-mc.edges[id].c);131             }132         } else puts("NO");133     }134     return 0;135 }
View Code

关于上下界网络流补充资料:http://blog.sina.com.cn/s/blog_76f6777d0101bara.html


Problem C ZOJ 2315 New Year Bonus Grant 树形dp或贪心

题意:以1为根的树中,每个结点可以从父节点获得一个奖励,或者自己给其中一个子节点的奖励,或者既不获得也不给出奖励。求所有结点获得的最大奖励数目

分析:我是用树形dp做的,dp[u][i],i为1表示从父亲结点获得奖励时该子树最大奖励和,dp[u][0]为不从父节点获得奖励时该子树的最大奖励和。

代码:

 1 #include <bits/stdc++.h> 2 #define pb push_back 3 #define mp make_pair 4  5 #define lson   l, m, rt<<1 6 #define rson   m+1, r, rt<<1|1 7 #define sz(x) ((int)((x).size())) 8 #define pb push_back 9 #define in freopen("solve_in.txt", "r", stdin);10 #define bug(x) printf("Line : %u >>>>>>\n", (x));11 #define inf 0x0f0f0f0f12 using namespace std;13 typedef long long LL;14 typedef map<int, int> MPS;15 typedef pair<int, int> PII;16 const int maxn = (int)5e5 + 100;17 vector<int> g[maxn];18 int dp[maxn][2], pa[maxn];19 void dfs(int u, int fa) {20     int sum = 0;21     dp[u][0] = dp[u][1] = -1;22     pa[u] = -1;23     for(int i = 0; i < sz(g[u]); i++) {24         int v = g[u][i];25         if(v == fa) continue;26         dfs(v, u);27         sum += dp[v][0];28     }29     dp[u][1] = 1 + sum;30     dp[u][0] = sum;31     for(int i = 0; i < sz(g[u]); i++) {32         int v = g[u][i];33         if(v == fa) continue;34         if(sum-dp[v][0]+dp[v][1] > dp[u][0])35             dp[u][0] = sum-dp[v][0]+dp[v][1], pa[u] = v;36     }37 }38 vector<int> ans;39 void printAns(int u, int st, int fa) {40     if(st) ans.pb(u);41     for(int i = 0; i < sz(g[u]); i++) {42         int v = g[u][i];43         if(v == fa) continue;44         printAns(v, v == pa[u] && !st, u);45     }46 }47 int main() {48     49     int T;50     for(int t = scanf("%d", &T); t <= T; t++) {51         if(t != 1) puts("");52         int n;53         ans.clear();54         scanf("%d", &n);55         for(int i = 1; i <= n; i++) g[i].clear();56         for(int i = 1; i < n; i++) {57             int u;58             scanf("%d", &u);59             g[u].pb(i+1);60         }61         dfs(1, 0);62         printf("%d\n", 1000*dp[1][0]);63         printAns(1, 0, 0);64         sort(ans.begin(), ans.end());65         for(int i = 0; i < (int)ans.size(); i++) {66             printf("%d%c", ans[i], i == (int)ans.size()-1 ? \n :  );67         }68     }69     return 0;70 }
View Code

 


Problem D ZOJ 2316 Matrix Multiplication 顶点度数

题意:给定一个图,n个顶点,m条边,最终就是要你求每个点度数平方之和。

分析:注意防止溢出。

 1 #include <bits/stdc++.h> 2 #define pb push_back 3 #define mp make_pair 4  5 #define lson   l, m, rt<<1 6 #define rson   m+1, r, rt<<1|1 7 #define sz(x) ((int)((x).size())) 8 #define pb push_back 9 #define in freopen("solve_in.txt", "r", stdin);10 #define bug(x) printf("Line : %u >>>>>>\n", (x));11 #define inf 0x0f0f0f0f12 using namespace std;13 typedef long long LL;14 typedef map<int, int> MPS;15 MPS mps;16 17 const int maxn = 10000 + 100;18 int num[maxn];19 int cnt;20 21 int idx(int x){22     if(mps.count(x) == false)23         mps[x] = ++cnt;24     return mps[x];25 }26 int main(){27     28     int T;29     for(int t = scanf("%d", &T); t <= T; t++){30         memset(num, 0, sizeof num);31         int n, m;32         mps.clear();33         cnt = 0;34         scanf("%d%d", &n, &m);35         for(int i = 1; i <= m; i++){36             int u, v;37             scanf("%d%d", &u, &v);38             u = idx(u);39             v = idx(v);40             num[u]++, num[v]++;41         }42         LL ans = 0;43         for(int i = 1; i <= n;i++){44             ans += (LL)num[i]*num[i];45         }46         if(t != 1) puts("");47         printf("%lld\n", ans);48     }49     return 0;50 }
View Code

 


Problem E ZOJ 2317 Nice Patterns Strike Back 矩阵快速幂,组合数

题意:一个n*m的方格,每个格子有两种颜色,现在给整个方格涂色,要求一个2*2的正方形内颜色不能相同,问有多少种颜色,m<=5, n <= 10^100,最终结果模p,p <= 10000。

分析:由于能否构成同样颜色正方形取决于当前列连续2格以及前一列的对应两列是否颜色一样,所以对每列的状态,st看能从哪些状态st‘转移过来。这样可以建立一个转移图

边u->v表示前一列状态为u下列可为v。dp[i+1][u]  = sum{dp[i][v]},可以得到一个矩阵,g[v][u]表示v转移到u,那么答案就是g^n然后取结果矩阵sum{g[i][0]}之和。

代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <map>  4 #include <cstring>  5 #include <vector>  6 #include <cmath>  7 #include <cassert>  8 #include <algorithm>  9 #define pb push_back 10 #define mp make_pair 11 #define esp 1e-8 12 #define lson   l, m, rt<<1 13 #define rson   m+1, r, rt<<1|1 14 #define sz(x) ((int)((x).size())) 15 #define pb push_back 16 #define in freopen("solve_in.txt", "r", stdin); 17 #define bug(x) printf("Line : %u >>>>>>\n", (x)); 18 #define inf 0x0f0f0f0f 19 using namespace std; 20 typedef long long LL; 21 typedef map<int, int> MPS; 22 typedef pair<int, int> PII; 23  24 const int maxn = 111; 25 const int maxm = 44; 26 const int B = 10000; 27 int m, p; 28  29 struct BigInt { 30     int dig[maxn], len; 31     BigInt(int num = 0):len(!!num) { 32         memset(dig, 0, sizeof dig); 33         dig[0] = num; 34     } 35     int operator [](int x)const { 36         return dig[x]; 37     } 38     int& operator [](int x) { 39         return dig[x]; 40     } 41     BigInt normalize() { 42         while(len && dig[len-1] == 0) len--; 43         return *this; 44     } 45     void output() { 46         if(len == 0) { 47             puts("0"); 48             return; 49         } 50         printf("%d", dig[len-1]); 51         for(int i = len-2; i >= 0; i--) 52             printf("%04d", dig[i]); 53         puts(""); 54     } 55 }; 56 BigInt operator / (BigInt a, int b) { 57     BigInt c; 58     c.len = a.len; 59     for(int i = a.len-1, delta = 0; i >= 0; i--) { 60         delta = delta*B+a[i]; 61         c[i] = delta/b; 62         delta %= b; 63     } 64     return c.normalize(); 65 } 66 bool operator == (const BigInt &a, const BigInt &b) { 67     if(a.len != b.len) return false; 68     for(int i = a.len-1; i >= 0; i--) if(a[i] != b[i]) return false; 69     return true; 70 } 71 struct Matrix { 72     int a[maxm][maxm]; 73     Matrix() { 74         memset(a, 0, sizeof a); 75     } 76 }; 77 Matrix operator * (const Matrix &a, const Matrix &b) { 78     Matrix c; 79     for(int i = 0; i < (1<<m)+1; i++) for(int j = 0; j < (1<<m)+1; j++) { 80             for(int k = 0; k < (1<<m)+1; k++) 81                 c.a[i][j] = (c.a[i][j] + (LL)a.a[i][k]*b.a[k][j]%p)%p; 82         } 83     return c; 84 } 85 char s[111]; 86 int b[] = {1, 10, 100, 1000}; 87  88 bool check(int x, int y) { 89     for(int i = 0; i < m-1; i++) { 90         if((((x>>i)&1) && ((x>>(i+1))&1) 91                 && ((y>>i)&1) && ((y>>(i+1))&1)) || (!((x>>i)&1) && !((x>>(i+1))&1) 92                 && !((y>>i)&1) && !((y>>(i+1))&1))) 93             return false; 94     } 95     return true; 96 } 97 int main() { 98      99 100     int T;101     for(int t = scanf("%d", &T); t <= T; t++) {102         if(t != 1) puts("");103         scanf("%s%d%d", s, &m, &p);104         int len = strlen(s);105         BigInt c;106         for(int i = len-1; i >= 0; i--) {107             c[(len-1-i)/4] += b[(len-1-i)%4]*(s[i]-0);108             c.len = max(c.len, (len-1-i)/4+1);109         }110         Matrix res, g;111         for(int i = 0; i < maxm; i++) for(int j = 0; j < maxm; j++) res.a[i][j] = i == j;112         for(int i = 0; i < (1<<m); i++) {113             g.a[i+1][0] = 1;114             for(int j = 0; j < (1<<m); j++) if(check(i, j)) {115                     g.a[j+1][i+1] = 1;116                 }117         }118         while(c.len) {119             if(c[0]&1) res = res*g;120             g = g*g;121             c = c/2;122         }123         int ans = 0;124         for(int i = 1; i <= (1<<m); i++)125             ans = (ans + res.a[i][0])%p ;126         printf("%d\n", ans);127     }128     return 0;129 }
View Code

 一个升级版的题目,不过要用到中国剩余定理:

hdu 4878 ZCC loves words AC自动机+中国剩余定理+快速幂


Problem F ZOJ 2318 Get Out! 有向角度判别法,spfa判负环

题意:给定一些圆,然后自己也是一个圆能否从中突出重围。

分析:将自己的半径加到其他圆上面,并平移坐标系以自己所在坐标为原点,将相交的圆心连一条边,然后问题变成了,看是否有一个多边形包围原点。利用有向视角判别法,每条边两个顶点与原点构成的角度a作为权值,对应原来的边建图,两条有向边,权值对应为a和-a。这样就看原图是否有负环了。利用spfa判别就行。位于多边形外面时显然角度和位0。内部则为360或-360度

注意:本题分析显然不会位于多边形顶点或边界上面,否则可能会出错?spfa判别法注意精度。

代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <map>  4 #include <cstring>  5 #include <vector>  6 #include <cmath>  7 #include <cassert>  8 #include <algorithm>  9 #include <queue> 10 #define pb push_back 11 #define mp make_pair 12 #define esp 1e-8 13 #define lson   l, m, rt<<1 14 #define rson   m+1, r, rt<<1|1 15 #define sz(x) ((int)((x).size())) 16 #define pf(x) ((x)*(x)) 17 #define pb push_back 18 #define in freopen("solve_in.txt", "r", stdin); 19 #define bug(x) printf("Line : %u >>>>>>\n", (x)); 20 #define inf 0x0f0f0f0f 21 using namespace std; 22 typedef long long LL; 23 typedef map<int, int> MPS; 24 typedef pair<int, int> PII; 25  26 const int maxn = 333; 27 double x[maxn], y[maxn], r[maxn], len[maxn]; 28  29 struct Edge { 30     int u, v; 31     double w; 32     Edge() {} 33     Edge(int u, int v, double w):u(u), v(v), w(w) {} 34 }; 35 vector<Edge> edges; 36 vector<int> g[maxn]; 37 int n, m; 38  39 void init() { 40     edges.clear(); 41     for(int i = 0; i < maxn; i++) g[i].clear(); 42 } 43 void add(int u, int v, double w) { 44     edges.pb(Edge(u, v, w)); 45     m = edges.size(); 46     g[u].pb(m-1); 47 } 48 inline bool check(double x1, double y1, double x2, double y2) { 49     return (x1*y2-y1*x2) >= 0; 50 } 51 int inq[maxn]; 52 double dist[maxn]; 53 int cnt[maxn]; 54  55 bool spfa() { 56     queue<int> q; 57     memset(inq, 0, sizeof inq); 58     for(int i = 1; i <= n; i++) { 59         inq[1] = 1; 60         cnt[i] = 0; 61         dist[i] = 0; 62         q.push(i); 63     }    while(q.size()) { 64         int u = q.front(); 65         q.pop(); 66         inq[u] = 0; 67         for(int i = 0; i < sz(g[u]); i++) { 68             Edge e = edges[g[u][i]]; 69             int v = e.v; 70             double c = e.w; 71             if(dist[v] > dist[u] + c + esp) { 72                 if(dist[v] = dist[u] + c, !inq[v]) { 73                     q.push(v); 74                     inq[v] = 1; 75                     if(++cnt[v] > n + 10) { 76                         return true; 77                     } 78                 } 79             } 80         } 81     } 82     return false; 83 } 84 int main() { 85      86     int T; 87     for(int t = scanf("%d", &T); t <= T; t++) { 88         if(t != 1) puts(""); 89         init(); 90         for(int i = scanf("%d", &n); i <= n+1; i++) { 91             scanf("%lf%lf%lf", x+i, y+i, r+i); 92         } 93         for(int i = 1; i <= n; i++) { 94             x[i] -= x[n+1]; 95             y[i] -= y[n+1]; 96             len[i] = sqrt(pf(x[i])+pf(y[i])); 97             r[i] += r[n+1]; 98         } 99         for(int i = 1; i <= n; i++)100             for(int j = i+1; j <= n; j++) {101                 if(sqrt(pf(x[i]-x[j]) + pf(y[i]-y[j])) >= r[i]+r[j])102                     continue;103                 double ang = acos((x[i]*x[j]+y[i]*y[j])/len[i]/len[j]);104                 bool ok = check(x[i], y[i], x[j], y[j]);105                 add(i, j, ok ? ang : -ang);106                 add(j, i, ok ? -ang : ang);107             }108         if(spfa())109             puts("NO");110         else puts("YES");111     }112     return 0;113 }
View Code

 

Problem G ZOJ 2319 Beautiful People LIS

题意:有n个元素,每个元素是一个对数ai,bi,然后从中选出一些元素,能够排成一列ai < ai+1, 且bi < bi+1,问最长选出多少个元素。

分析:看上去像是LIS,其实也是利用这个,由于ai肯定是单调递增的,所以先按ai小到大排序,bi从大到小排序,然后只要按照bi选出LIS就行了。利用O(nlogn)的经典做法可做。

代码:

 1 #include <bits/stdc++.h> 2 #define pb push_back 3 #define mp make_pair 4  5 #define lson   l, m, rt<<1 6 #define rson   m+1, r, rt<<1|1 7 #define sz(x) ((int)((x).size())) 8 #define pb push_back 9 #define in freopen("solve_in.txt", "r", stdin);10 #define bug(x) printf("Line : %u >>>>>>\n", (x));11 #define inf 0x0f0f0f0f12 using namespace std;13 typedef long long LL;14 typedef map<int, int> MPS;15 typedef pair<int, int> PII;16 17 const int maxn = (int)1e5 + 100;18 int f[maxn], dp[maxn];19 MPS mps;20 21 struct Node {22     int s, b, id;23     Node() {}24     Node(int s, int b, int id):s(s), b(b), id(id) {}25     bool operator < (const Node &rhs)const {26         if(s != rhs.s) return s < rhs.s;27         return b > rhs.b;28     }29 } a[maxn];30 int g[maxn];31 int cnt;32 int idx(int x) {33     if(mps.count(x) == false)34         mps[x] = ++cnt;35     return mps[x];36 }37 38 int main() {39     40     int T;41     for(int t = scanf("%d", &T); t <= T; t++) {42         int n;43         cnt = 0;44         if(t != 1) puts("");45         scanf("%d", &n);46         mps.clear();47         for(int i = 1; i <= n; i++) {48             scanf("%d%d", &a[i].s, &a[i].b);49 ////            a[i].s = idx(a[i].s);50 ////            a[i].b = idx(a[i].b);51             a[i].id = i;52         }53         memset(dp, 0, sizeof dp);54         sort(a+1, a+n+1);55         memset(f, 0x7f, sizeof f);56         int ans = 0, u;57         for(int i = 1; i <= n; i++) {58             int k = lower_bound(f+1, f+n+1, a[i].b)-f-1;59             if(ans < k+1)60                 ans = k+1, u = i;61             f[k+1] = a[i].b;62             g[k+1] = i;63             dp[i] = g[k];64         }65         cout << ans << endl;66         int ok = 0;67         while(u) {68             if(ok) cout <<  ;69             else ok ^= 1;70             cout << a[u].id;71             u = dp[u];72         }73         puts("");74     }75     return 0;76 }
View Code

 


Problem H ZOJ 2320 Cracking‘ RSA 高斯消元

题意:给定m个数,其素因子来自前t个素数,m <= 100,t <= 100。求m个数构成的集合,从中选出一些数构成子集,所有元素之积为完全平方数。有多少种方案。

分析:考虑每个数有选和不选两种状态,用未知量xi表示,由于最终选出来的数的积为完全平方数,所以其乘积中,对于前t个素数的数目必须为偶数个,即模2为0。

所以容易建立t个方程,对每个数分解质因数,质因数个数模2为0,这是一个线性方程组,方程一定有解,所以设自由元个数n,答案2^n-1,这里要用到大数。

代码:

 

  1 #include <iostream>  2 #include <cstdio>  3 #include <map>  4   5 #include <cstring>  6 #include <vector>  7 #include <cmath>  8 #include <cassert>  9 #include <algorithm> 10 #define pb push_back 11 #define mp make_pair 12 #define esp 1e-8 13 #define lson   l, m, rt<<1 14 #define rson   m+1, r, rt<<1|1 15 #define sz(x) ((int)((x).size())) 16 #define pb push_back 17 #define in freopen("solve_in.txt", "r", stdin); 18 #define bug(x) printf("Line : %u >>>>>>\n", (x)); 19 #define inf 0x0f0f0f0f 20 using namespace std; 21 typedef long long LL; 22 typedef map<int, int> MPS; 23 typedef pair<int, int> PII; 24  25 const int maxn = 110; 26 const int B = 10000; 27  28 int num[maxn][maxn], prime[maxn], vis[2222]; 29 int a[maxn][maxn]; 30 void seivePrime() { 31     int tot = 0; 32     for(int i = 2; i < 2000; i++) { 33         if(!vis[i]) prime[++tot] = i; 34  35         for(int j = 1; j <= tot; j++){ 36             if(prime[j]*i >= 2000) break; 37             vis[i*prime[j]] = 1; 38             if(i%prime[j] == 0) break; 39         } 40         if(tot >= 150) break; 41     } 42 } 43 int n, m; 44 void getFact(int b, LL x) { 45     for(int i = 1; i <= n; i++) { 46         if(x%prime[i] == 0) { 47             while(x%prime[i] == 0) { 48                 num[b][i-1]++; 49                 x /= prime[i]; 50             } 51             if(x == 1) 52                 break; 53         } 54     } 55 } 56 int Gauss(int equ, int var) { 57     int k, r, col; 58     for(k = col = 0; k < equ && col < var; k++, col++) { 59         r = k; 60         for(int i = k+1; i < equ; i++) if(a[i][col]) { 61                 r = i; 62                 break; 63             } 64         if(r != k) for(int i = col; i <= var; i++) 65                 swap(a[r][i], a[k][i]); 66         if(a[k][col] == 0) { 67             k--; 68             continue; 69         } 70         for(int i = k+1; i < equ; i++) if(a[i][col]) 71                 for(int j = col; j <= var; j++) 72                     a[i][j] ^= a[k][j]; 73     } 74     return var-k; 75 } 76 struct BigInt { 77     int dig[maxn], len; 78     BigInt(int num = 0):len(!!num) { 79         memset(dig, 0, sizeof dig); 80         dig[0] = num; 81     } 82     int operator [](int x)const { 83         return dig[x]; 84     } 85     int &operator [](int x) { 86         return dig[x]; 87     } 88     BigInt normalize() { 89         while(len > 1 && dig[len-1] == 0) len--; 90         return *this; 91     } 92     void output() { 93         printf("%d", dig[len-1]); 94         for(int i = len-2; i >= 0; i--) 95             printf("%04d", dig[i]); 96         puts(""); 97     } 98 }; 99 BigInt operator - (BigInt a, int b) {100     BigInt c;101     c.len = a.len;102     for(int i = 0, delta = -b; i < a.len; i++) {103         c[i] = delta+a[i];104         delta = 0;105         if(c[i] < 0) {106             delta = -1;107             c[i] = c[i]+B;108         }109     }110     return c.normalize();111 }112 BigInt operator *(BigInt a, BigInt b) {113     BigInt c;114     c.len = a.len+b.len+1;115     for(int i = 0; i < a.len; i++)116         for(int j = 0, delta = 0; j <= b.len; j++) {117             delta += (c[i+j]+a[i]*b[j]);118             c[i+j] = delta%B;119             delta /= B;120         }121     return c.normalize();122 }123 void print(int x){124      int i , len = 1 , ans[100];125      memset(ans,0,sizeof(ans));126      ans[1] = 1;127      while (x--){128            for (i=1;i<=len;++i) ans[i]*=2;129            for (i=1;i<=len;++i)130                ans[i+1] += ans[i]/10 , ans[i] %= 10;131            if (ans[len+1]) ++len;132      }133      --ans[1];134      for (i=len;i>=1;--i) printf("%d",ans[i]);135      puts("");136 }137 int main() {138 139     int T;140     seivePrime();141     for(int t = scanf("%d", &T); t <= T; t++) {142         if(t != 1) puts("");143         memset(num, 0, sizeof num);144         memset(a, 0, sizeof a);145         scanf("%d%d", &n, &m);146         for(int i = 0; i < m; i++) {147             int x;148             scanf("%d", &x);149             for(int ii = 1; ii <= n; ii++) {150                 if(x%prime[ii] == 0) {151                     while(x%prime[ii] == 0) {152                         a[ii-1][i] ^= 1;153                         x /= prime[ii];154                     }155                 }156             }157         }158         int vary = Gauss(n, m);159         if(vary == 0) puts("0");160         else161         print(vary);162     }163     return 0;164 }
View Code

 

ASC #1