牛客練習賽29: F. 算式子
阿新 • • 發佈:2018-12-16
題目描述
給定 個整數 。保證 。
對於每個 ,求出 。為了避免過量輸出,你只需要將所有的 m 個結果異或起來輸出。
輸入描述:
第一行兩個整數 。
第二行 個整數,第 個表示 。
輸出描述:
一行一個整數,表示所有結果異或起來的結果。
輸入
2 2 1 2
輸出
0
思路:
算一下每個a[i]/x的貢獻和每個x/a[i]的貢獻
然後就是類似於質數篩的過程,對於每個i∈[1, m]暴力它所有的倍數
複雜度O(mlnm)
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 int sum[4005005]; LL ans[2005005], dx[4005005]; int main(void) { LL now, bet; int n, m, i, x, j; scanf("%d%d", &n, &m); for(i=1;i<=n;i++) { scanf("%d", &x); sum[x]++; } for(i=1;i<=m*2;i++) sum[i] += sum[i-1]; for(i=1;i<=m;i++) { for(j=1;j*i<=m;j++) { ans[i] += (LL)j*(sum[i*(j+1)-1]-sum[i*j-1]); dx[i*j] += (LL)j*(sum[i]-sum[i-1]); dx[i*(j+1)] -= (LL)j*(sum[i]-sum[i-1]); } } bet = now = 0; for(i=1;i<=m;i++) { now += dx[i]; ans[i] += now; bet ^= ans[i]; } printf("%lld\n", bet); return 0; }