15.5.10 国防科大校赛

题目链接http://acm.csu.edu.cn/OnlineJudge/contest.php?cid=2080

problemset 1609~1618

比赛完几天了 却一直没有写题解,比赛中是完全被虐了的,赛后做的差不多了这下就写写题解。

 

A:Arrays Transformation(YY)

题目是说一个数组每次可以将连续的三个数(a[i-1], a[i], a[a+1])变为(a[i-1]+a[i], -a[i], a[i+1]+a[i]),现在给定A和B两个序列,问是否可以通过多次操作使得序列由A变为B

方法就是因为每次操作i,相当于把前缀和s[i-1]和s[i]互换位置,认真想一下很好明白,所以最后就转化为判断是否两个数组的前缀和排序后是不是可以通过排序后一一对应起来

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25  
26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
32  
33 //typedef __int64 LL;
34 typedef long long LL;
35 const int MAXN = 51000;
36 const int MAXM = 110000;
37 const double eps = 1e-4;
38 //LL MOD = 987654321;
39  
40 LL a[110000], b[110000];
41 int T, n, x;
42  
43 int main()
44 {
45     //FIN;
46     while(~scanf("%d", &T)) while(T--) {
47         cin >> n;
48         rep (i, 1, n) scanf("%d", &x), a[i] = a[i - 1] + x;
49         rep (i, 1, n) scanf("%d", &x), b[i] = b[i - 1] + x;
50         sort(a + 1, a + n + 1);
51         sort(b + 1, b + n + 1);
52         int ok = 1;
53         rep (i, 1, n) if(a[i] != b[i]) ok = 0;
54         puts(ok ? "Yes" : "No");
55     }
56     return 0;
57 }
View Code

 

B:Binary Subtraction(二进制高精度减法)

不用说了,水题

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25 #define dec(i, a, b) for(int i = a; i >= b; i --)
26  
27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
33  
34 //typedef __int64 LL;
35 typedef long long LL;
36 const int MAXN = 51000;
37 const int MAXM = 110000;
38 const double eps = 1e-4;
39 //LL MOD = 987654321;
40  
41 int T, n, m, x;
42 int a[1100000], b[1100000];
43  
44 int main()
45 {
46     //FIN;
47     while(~scanf("%d", &T)) while(T--) {
48         cin >> n >> m;
49         rep (i, 1, n) a[i] = 1, b[i] = 0;
50         rep (i, 1, m) {
51             scanf("%d", &x);
52             a[x] = 0; b[x] = 1;
53         }
54         int ji = 0;
55         rep (i, 1, n) {
56             if(ji) {
57                 if(a[i] == 0) { ji = 1; a[i] = !b[i]; }
58                 else { ji = b[i]; a[i] = b[i]; }
59             }
60             else {
61                 if(a[i] == 0) { ji = b[i]; a[i] = b[i]; }
62                 else { ji = 0; a[i] -= b[i]; }
63             }
64         }
65         int f = 0;
66         dec (i, n, 1) {
67             if(a[i]) f = 1;
68             if(f) printf("%d", a[i]);
69         }
70         printf("\n");
71     }
72     return 0;
73 }
View Code

 

C:Concatenation(TSP问题)

题意是说给n(<=12)个字符串,问求一个最短的字符串,使得它包含所有的给定字符串

由于如果一个字符串完全被另一个字符串包含(是另一个字符串的子串),那么这个字符串完全可以不予考虑,将其删除

接下来就是简单的状压DP

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25  
26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
32  
33 //typedef __int64 LL;
34 typedef long long LL;
35 const int MAXN = 51000;
36 const int MAXM = 110000;
37 const double eps = 1e-4;
38 //LL MOD = 987654321;
39  
40 int mer[20][20], len[20], dp[1<<15][20], n, t, vis[55];
41 char s[20][55];
42  
43 int Strstr(char *a, char *b) {
44     int lena = strlen(a), lenb = strlen(b);
45     rep (i, 0, lena - 1) {
46         int j = 0;
47         while(i + j < lena && j < lenb && a[i + j] == b[j]) j++;
48         if(j == lenb) return i;
49     }
50     return -1;
51 }
52  
53 //find suffix of a with the max length is pre of b
54 int findMerge(char *a, char *b) {
55     int lena = strlen(a), lenb = strlen(b);
56     rep (i, 0, lena - 1) {
57         if(Strstr(b, a + i) == 0) return lena - i;
58     }
59     return 0;
60 }
61  
62 int main()
63 {
64     while(~scanf("%d", &t)) while(t--) {
65         scanf("%d", &n);
66         rep(i, 0, n - 1) scanf("%s", s[i]);
67         mem0(vis);
68         rep (i, 0, n - 1) rep (j, i+1, n - 1) {
69             if(Strstr(s[i], s[j]) >= 0) vis[j] = 1;
70             else if(Strstr(s[j], s[i]) >= 0) vis[i] = 1;
71         }
72  
73         int cnt = 0;
74         rep (i, 0, n - 1) {
75             if(!vis[i]) {
76                 strcpy(s[cnt++], s[i]);
77                 len[cnt-1] = strlen(s[cnt-1]);
78             }
79         }
80         rep (i, 0, cnt - 1) rep (j, 0, cnt - 1) {
81             mer[i][j] = findMerge(s[i], s[j]);
82         }
83  
84         mem1(dp);
85         int high = (1 << cnt) - 1;
86         rep (i, 0, cnt - 1) dp[1 << i][i] = len[i];
87         rep (i, 1, high) rep (j, 0, cnt - 1) if((i & (1<<j)) && dp[i][j] != -1) {
88             rep (k, 0, cnt - 1) if(!(i & (1 << k))) {
89                 if(dp[i | (1<<k)][k] == -1) dp[i | (1<<k)][k] = dp[i][j] + len[k] - mer[j][k];
90                 else dp[i | (1<<k)][k] = min(dp[i | (1<<k)][k], dp[i][j] + len[k] - mer[j][k]);
91             }
92         }
93         int ans = 1000000;
94         rep (i, 0, cnt - 1) ans = min(ans, dp[high][i]);
95         cout << ans << endl;
96     }
97     return 0;
98 }
99  
View Code

 

D:Destroy Tunnels(强连通)

连接

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25 #define dec(i, a, b) for(int i = a; i >= b; i --)
26  
27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
33  
34 //typedef __int64 LL;
35 typedef long long LL;
36 const int MAXN = 11000;
37 const int MAXM = 1100;
38 const double eps = 1e-4;
39 LL MOD = 1000000007;
40  
41 vector<int> G[MAXN];
42 int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;
43 stack<int>S;
44  
45 void dfs(int u)
46 {
47     pre[u] = lowlink[u] = ++dfs_clock;
48     S.push(u);
49     int si = G[u].size();
50     for(int i = 0; i < si; i ++)
51     {
52         int v = G[u][i];
53         if(!pre[v]) {
54             dfs(v);
55             lowlink[u] = min(lowlink[u], lowlink[v]);
56         }
57         else if(!sccno[v]) {
58             lowlink[u] = min(lowlink[u], pre[v]);
59         }
60     }
61     if(lowlink[u] == pre[u]) {
62         scc_cnt++;
63         for(;;) {
64             int x = S.top(); S.pop();
65             sccno[x] = scc_cnt;
66             if(x == u) break;
67         }
68     }
69 }
70  
71  
72 void find_scc(int n)
73 {
74     dfs_clock = scc_cnt = 0;
75     mem0(sccno); mem0(pre);
76     for(int i = 0; i < n; i ++ )
77         if(!pre[i]) dfs(i);
78 }
79  
80 int t, n, x;
81  
82 int main()
83 {
84     while(~scanf("%d", &t)) while(t--) {
85         scanf("%d", &n);
86         rep (i, 0, n) G[i].clear();
87         rep (i, 0, n - 1) rep (j, 0, n - 1) {
88             scanf("%d", &x);
89             if(x) G[i].push_back(j);
90         }
91         find_scc(n);
92         puts(scc_cnt == 1 ? "not exists" : "exists");
93     }
94     return 0;
95 }
96  
View Code

 

E:Elephants(分组背包)

裸的

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25 #define dec(i, a, b) for(int i = a; i >= b; i --)
26  
27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
33  
34 //typedef __int64 LL;
35 typedef long long LL;
36 const int MAXN = 11000;
37 const int MAXM = 1100;
38 const double eps = 1e-4;
39 LL MOD = 1000000007;
40  
41 int t, n, m, c, w, v, f[21][1100];
42  
43 int main()
44 {
45     //FIN;
46     while(~scanf("%d", &t)) while(t--) {
47         scanf("%d %d", &n, &m);
48         mem0(f);
49         rep (i, 1, n) {
50             scanf("%d", &c);
51             rep (j, 1, c) {
52                 scanf("%d %d", &w, &v);
53                 rep (k, 0, w - 1) f[i][k] = max(f[i][k], f[i - 1][k]);
54                 rep (k, w, m) f[i][k] = max(f[i][k], max(f[i - 1][k], f[i - 1][k - w] + v));
55             }
56         }
57         printf("%d\n", f[n][m]);
58     }
59     return 0;
60 }
View Code

 

F:First Blood(水题)

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25 #define dec(i, a, b) for(int i = a; i >= b; i --)
26  
27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
33  
34 //typedef __int64 LL;
35 typedef long long LL;
36 const int MAXN = 11000;
37 const int MAXM = 1100;
38 const double eps = 1e-4;
39 LL MOD = 1000000007;
40  
41 int t, n;
42 double x[110], y[110], r[110];
43  
44 double dis(int i, int j) {
45     double a = x[i] - x[j], b = y[i] - y[j];
46     return (double) sqrt(a * a + b * b);
47 }
48  
49 int main()
50 {
51     //FIN;
52     while(~scanf("%d", &t)) while(t--) {
53         scanf("%d", &n);
54         rep (i, 1, n) scanf("%lf %lf %lf", x + i, y + i, r + i);
55         int ans = 0;
56         rep (i, 1, n) {
57             int ok = 1;
58             rep (j, 1, n) if(i != j) {
59                 if(r[i] + r[j] - dis(i, j) > eps) { ok = 0; break; }
60             }
61             ans += ok;
62         }
63         printf("%d\n", ans);
64     }
65     return 0;
66 }
67  
View Code

 

G:Garden(小学数学题)

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25 #define dec(i, a, b) for(int i = a; i >= b; i --)
26  
27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
33  
34 //typedef __int64 LL;
35 typedef long long LL;
36 const int MAXN = 11000;
37 const int MAXM = 1100;
38 const double eps = 1e-4;
39 LL MOD = 1000000007;
40  
41 int A, B, C,t;
42  
43 int main()
44 {
45     //FIN;
46     while(~scanf("%d", &t)) while(t--) {
47         scanf("%d %d %d", &A, &B, &C);
48         int x = 2 * A * B * C / (B * C + A * B - A* C);
49         int y = A * x / (x - A);
50         int z = C * x / (x - C);
51         printf("%d %d %d\n", x, y, z);
52     }
53     return 0;
54 }
View Code

 

H:Heaps(石子合并-四边形不等式)

见我的另一篇题解http://www.cnblogs.com/gj-Acit/p/4493512.html

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, (L + R)>>1
18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FIN freopen("in.txt", "r", stdin)
23 #define FOUT freopen("out.txt", "w", stdout)
24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
25  
26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
32  
33 //typedef __int64 LL;
34 typedef long long LL;
35 const int MAXN = 51000;
36 const int MAXM = 110000;
37 const double eps = 1e-4;
38 //LL MOD = 987654321;
39  
40 int T, n, m, s[1100], a[10];
41 LL p[1100][1100], dp[1100][1100];
42  
43 LL fun(int x) {
44     LL ans = 0, p = 1;
45     rep (i, 0, m) {
46         ans += a[i] * p;
47         p *= x;
48     }
49     return ans;
50 }
51  
52 int main()
53 {
54     //FIN;
55     while(~scanf("%d", &T)) while(T--) {
56         scanf("%d", &n);
57         rep (i, 1, n) scanf("%d", s + i), s[i] += s[i - 1];
58         scanf("%d", &m);
59         rep (i, 0, m) scanf("%d", a + i);
60         mem0(dp); mem0(p);
61         rep (len, 1, n) {
62             rep (i, 1, n - len + 1) {
63                 int j = i + len - 1;
64                 LL cost = fun(s[j] - s[i - 1]);
65                 if(len <= 1) { dp[i][j] = 0; p[i][j] = i; }
66                 else rep (k, p[i][j - 1], p[i + 1][j]) {
67                     if(dp[i][k] + dp[k+1][j] + cost < dp[i][j] || dp[i][j] == 0) {
68                         p[i][j] = k;
69                         dp[i][j] = dp[i][k] + dp[k+1][j] + cost;
70                     }
71                 }
72             }
73         }
74         cout << dp[1][n] << endl;
75     }
76     return 0;
77 }
78  
View Code

 

I:Itself is Itself(强连通分量)

若一个子集满足子集值域与定义域完全一致,则正好可以看做这些点组成了一个自环(在一个强连通分量里),至于为什么可以看做是x->P(x)连一条边,这时边便代表关系映射,点则代表值,如果定义域与值域正好完全重叠,可以看做是正好这些点组成一个自环,最后转化为求强连通分量的个数,这里要去掉没有自环且点数只有1个点的分量,因为这些定义域导致与的关系映射不能作为答案。

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 0x3f3f3f3f
 16 #define inf (-((LL)1<<40))
 17 #define lson k<<1, L, (L + R)>>1
 18 #define rson k<<1|1,  ((L + R)>>1) + 1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FIN freopen("in.txt", "r", stdin)
 23 #define FOUT freopen("out.txt", "w", stdout)
 24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
 25 #define dec(i, a, b) for(int i = a; i >= b; i --)
 26  
 27 template<class T> T CMP_MIN(T a, T b) { return a < b; }
 28 template<class T> T CMP_MAX(T a, T b) { return a > b; }
 29 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 30 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 31 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 32 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 33  
 34 //typedef __int64 LL;
 35 typedef long long LL;
 36 const int MAXN = 11000;
 37 const int MAXM = 1100;
 38 const double eps = 1e-4;
 39 LL MOD = 1000000007;
 40  
 41  
 42 vector<int> G[MAXN];
 43 int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;
 44 stack<int>S;
 45  
 46 void dfs(int u)
 47 {
 48     pre[u] = lowlink[u] = ++dfs_clock;
 49     S.push(u);
 50     int si = G[u].size();
 51     for(int i = 0; i < si; i ++)
 52     {
 53         int v = G[u][i];
 54         if(!pre[v]) {
 55             dfs(v);
 56             lowlink[u] = min(lowlink[u], lowlink[v]);
 57         }
 58         else if(!sccno[v]) {
 59             lowlink[u] = min(lowlink[u], pre[v]);
 60         }
 61     }
 62     if(lowlink[u] == pre[u]) {
 63         scc_cnt++;
 64         for(;;) {
 65             int x = S.top(); S.pop();
 66             sccno[x] = scc_cnt;
 67             if(x == u) break;
 68         }
 69     }
 70 }
 71  
 72  
 73 void find_scc(int n)
 74 {
 75     dfs_clock = scc_cnt = 0;
 76     mem0(sccno); mem0(pre);
 77     for(int i = 0; i < n; i ++ )
 78         if(!pre[i]) dfs(i);
 79 }
 80  
 81 int t, n, m, a[MAXM];
 82  
 83 int P(int x) {
 84     LL ans = 0, p = 1;
 85     rep (i, 0, m) {
 86         ans = (ans + a[i] * p) % n;
 87         p = p * x % n;
 88     }
 89     return (int)ans;
 90 }
 91  
 92 int num[MAXN];
 93  
 94 int main()
 95 {
 96     //make_data();
 97     //FIN; freopen("gj.txt", "w", stdout);
 98     while(~scanf("%d", &t)) while(t--) {
 99         scanf("%d %d", &n, &m);
100         rep (i, 0, m) scanf("%lld", &a[i]);
101         int self = 0;
102         rep (i, 0, n - 1) G[i].clear();
103         rep (u, 0, n - 1) {
104             int v = P(u);
105             if(u == v) { self ++; continue; }
106             G[u].push_back(v);
107         }
108         find_scc(n);
109         mem0(num);
110         int cnt = self;
111         rep (i, 0, n - 1) num[sccno[i]] ++;
112         rep (i, 1, scc_cnt) cnt += num[i] >= 2;
113         LL ans = 1;
114         while(cnt--) {
115             ans = (ans + ans) % MOD;
116         }
117         cout << ans << endl;
118     }
119     return 0;
120 }
View Code

 

posted @ 2015-05-13 02:33  再见~雨泉  阅读(244)  评论(0编辑  收藏  举报