zoukankan      html  css  js  c++  java
  • 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 >>>>>>
    ", (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 = 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 = 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
    ", 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 >>>>>>
    ", (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 = (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
    ", 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 ? '
    ' : ' ');
    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 >>>>>>
    ", (x));
    11 #define inf 0x0f0f0f0f
    12 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
    ", 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 >>>>>>
    ", (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
    ", 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 >>>>>>
    ", (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 >>>>>>
    ", (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 
    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 >>>>>>
    ", (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         else
    161         print(vary);
    162     }
    163     return 0;
    164 }
    View Code
  • 相关阅读:
    hdu 4297 One and One Story 夜
    hdu 4280 Island Transport 夜
    1389. Roadworks 夜
    hdu 4289 Control 夜
    hdu 4291 A Short problem 夜
    hdu 4284 Travel 夜
    1080. Map Coloring 夜
    正则中的转义符\
    起重复出现作用的量词*和+
    安卓的权限大全和动态使用安卓权限
  • 原文地址:https://www.cnblogs.com/rootial/p/4075129.html
Copyright © 2011-2022 走看看