BZOJ 4454: C Language Practice

4454: C Language Practice

Time Limit: 20 Sec  Memory Limit: 24 MB
Submit: 501  Solved: 112
[Submit][Status][Discuss]

Description

Input

第一行输入一个正整数T(T<=85),表示测试数据的组数。
每组数据第一行包含两个正整数n,m(1<=n,m<=2000),表示序列的长度。
第二行包含n个正整数,表示a[0],a[1],...,a[n-1](0<=a[i]<=1000000)。
第三行包含m个正整数,表示b[0],b[1],...,b[m-1](0<=b[i]<=1000000)。

 

Output

对于每组数据输出一行一个整数,即答案。

 

Sample Input

3
3 2
5 9 6
3 4
2 2
8 9
0 6
1 1
9
6

Sample Output

6
22
3

HINT

 

注意:此题只有一个数据点。

 

Source

 
[Submit][Status][Discuss]

 

$O(N)-O(1)$的gcd黑科技

 

  1 #include <cstdio>
  2 
  3 inline char Char(void)
  4 {
  5     static const int siz = 1024;
  6     
  7     static char buf[siz];
  8     static char *hd = buf + siz;
  9     static char *tl = buf + siz;
 10     
 11     if (hd == tl)
 12         fread(hd = buf, 1, siz, stdin);
 13     
 14     return *hd++;
 15 }
 16 
 17 inline int Int(void)
 18 {
 19     int ret = 0, neg = 0, c = Char();
 20     
 21     for (; c < 48; c = Char())
 22         if (c == '-')neg ^= true;
 23     
 24     for (; c > 47; c = Char())
 25         ret = ret * 10 + c - '0';
 26     
 27     return neg ? -ret : ret;
 28 }
 29 
 30 int g[1005][1005];
 31 
 32 int fac[1000005][3];
 33 
 34 int pre[1000005], pri[1000005], tot;
 35 
 36 inline int gcd(int a, int b)
 37 {
 38     if (a <= 1000 && b <= 1000)
 39         return g[a][b];
 40     
 41     int ret = 1;
 42     
 43     for (int i = 0; i < 3; ++i)
 44         if (fac[a][i] != 1)
 45         {
 46             int t = fac[a][i];
 47             
 48             if (pre[t])
 49             {
 50                 int d = g[t][b % t];
 51                 ret *= d, b /= d;
 52             }
 53             else if (b % t == 0)
 54                 ret *= t, b /= t;
 55         }
 56     
 57     return ret;
 58 }
 59 
 60 signed main(void)
 61 {
 62     for (int i = 0; i <= 1000; ++i)
 63         for (int j = 0; j <= 1000; ++j)
 64             if (i == 0 || j == 0)
 65                 g[i][j] = i + j;
 66             else if (g[j][i % j])
 67                 g[i][j] = g[j][i % j];
 68             else if (g[i % j][j])
 69                 g[i][j] = g[i % j][j];
 70             else if (g[i][j % i])
 71                 g[i][j] = g[i][j % i];
 72             else if (g[j % i][i])
 73                 g[i][j] = g[j % i][i];
 74     
 75     fac[1][0] = fac[1][1] = fac[1][2] = 1;
 76     
 77     for (int i = 2; i <= 1000000; ++i)
 78     {
 79         if (!pre[i])pri[++tot] = i,
 80             fac[i][0] = fac[i][1] = 1, fac[i][2] = i;
 81         
 82         for (int j = 1; j <= tot && pri[j] * i <= 1000000; ++j)
 83         {
 84             int num = pri[j] * i, p = pri[j];
 85             
 86             pre[num] = p;
 87             fac[num][0] = fac[i][0];
 88             fac[num][1] = fac[i][1];
 89             fac[num][2] = fac[i][2];
 90             
 91             if (fac[num][0] * p <= 1000)
 92                 fac[num][0] *= p;
 93             else if (fac[num][1] * p <= 1000)
 94                 fac[num][1] *= p;
 95             else
 96                 fac[num][2] *= p;
 97         }
 98     }
 99     
100     for (int cas = Int(); cas--; )
101     {
102         static int n, m, a[2005], b[2005];
103         
104         n = Int();
105         m = Int();
106         
107         for (int i = 0; i < n; ++i)
108             a[i] = Int();
109         
110         for (int i = 0; i < m; ++i)
111             b[i] = Int();
112         
113         unsigned ans = 0;
114         
115         for (int i = 0; i < n; ++i)
116             for (int j = 0; j < m; ++j)
117                 ans += gcd(a[i], b[j]) ^ i ^ j;
118         
119         printf("%u\n", ans);
120     }
121 }

 

@Author: YouSiki

 

posted @ 2017-01-12 16:37  YouSiki  阅读(302)  评论(0编辑  收藏  举报