HDU多校2017第7场
6121 Build a tree
6125 Free from square
6126 Give out candies
6127 Hard challenge
6128 Inverse of sum
式子$\frac{1}{a+b}\equiv \frac{1}{a}+\frac{1}{b}(mod\ p)$可化为$a^2+ab+b^2 \equiv 0(mod\ p)$。当$a=b$时,可转化为$3a^2 \equiv 0(mod\ p)$,此时,只有$p=3$时才成立(因为$p$必须是素数)。当$a \ne b$时,把式子$a^2+ab+b^2 \equiv 0(mod\ p)$两边同时乘$(a-b)$,得到$a^3-b^3 \equiv 0(mod\ p),\Longrightarrow a^3 \equiv b^3(mod\ p)$。
因此:
当$p=3$时,只需要分别统计$1$和$2$的个数$cnt1$和$cnt2$,答案就是$A_{cnt1}^2+A_{cnt2}^2$。
当$p \ne 3$时,必然是$a \ne b$,对于元素$x$而言,需要找到一些$y$,满足:$x \ne y$且$x^3 \equiv y^3(mod\ p)$。这时,因为$max(p)=10^{18}$,计算$y^3(mod\ p)$时会溢出,所以需要用到快速乘法。
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define MAXN 100010 LL a[MAXN], n, p; LL calc(){ LL res = 0; a[n] = -1; for(int i = 1, cnt = 1;i <= n;++i){ if(a[i] == a[i - 1])cnt++; else{ res += LL(cnt - 1) * cnt / 2; cnt = 1; } } return res; } LL qmult(LL x, LL y){ LL res = 0; if(x < y)swap(x, y); while(y){ if(y & 1)res = (res + x) % p; x = (x << 1) % p; y >>= 1; } return res; } int main(){ int T; scanf("%d", &T); while(T--){ scanf("%I64d%I64d", &n, &p); for(int i = 0;i < n;++i)scanf("%I64d", a + i); if(p == 3){ int cnt1 = 0, cnt2 = 0; for(int i = 0;i < n;++i){ if(a[i] == 1)cnt1++; else if(a[i] == 2) cnt2++; } LL ans = LL(cnt1 - 1) * cnt1 / 2 + LL(cnt2 - 1) * cnt2 / 2; cout << ans << endl; }else{ sort(a, a + n); LL ans = -calc(); for(int i = 0;i < n;++i)a[i] = qmult(a[i], qmult(a[i], a[i])); sort(a, a + n); ans += calc(); cout << ans << endl; } } return 0; }
6129 Just do it
对于变换$m$次之后的序列,考虑$a_0$对$a_i(0 \le i < n)$的贡献,为$C_{m-1+i}^i$个$a_0$相异或的结果。同样地,$a_1$对$a_{i+1}(0 \le i<n-1)$的贡献也为$C_{m-1+i}^i$。然后,组合数判定奇偶性:杨辉三角第$i$行第$j$列的元素为$C_i^j$,如果$(i \& j) == j$,则$C_i^j$为奇数,否则为偶数。接下来,只需要枚举$a_0$对$a_i(0 \le i < n)$的贡献,若为奇数,则$a_1$对$a_{i+1}$的贡献,$a_2$对$a_{i+2}$的贡献,$\dots$,只需要暴力做相同的处理即可。放心,不会超时的。我随机造了几十组数据规模$2 \times 10^5$的大数据,有的数据需要迭代近$4 \times 10^8$次,只需要300+ms左右就能迭代完。下面的代码通过hdu所有数据的测试,只需要900+ms。而且是在没做任何常数优化的情况下。
另外,杨辉三角具有一个性质:用$P_n$表示$n$层三角形中奇数的占比,有:${\lim\limits_{n \to \infty}P_n \to 0}$。
#include<bits/stdc++.h> using namespace std; #define MAXN 200010 int a[MAXN], b[MAXN], n, m; int main(){ //freopen("input.txt", "r", stdin); int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); for(int i = 0;i < n;++i)scanf("%d", a + i); memset(b, 0, sizeof(b)); for(int i = 0;i < n;++i){ if((((m - 1) + i) & i) == i){ for(int j = i, k = 0;j < n;++j,++k){ b[j] ^= a[k]; } } } // cout << cnt << " " << clock() - st << endl; for(int i = 0;i < n;++i)printf("%d%c", b[i], i == n - 1 ? '\n' : ' '); } return 0; }
posted on 2018-07-21 00:02 鹤鸣于九皋,声闻于天 阅读(177) 评论(0) 编辑 收藏 举报