题目链接:https://ac.nowcoder.com/acm/contest/6290/E
这个题目要将求得的m个结果进行异或后输出结果。
对于每一个结果x的值是一定的,但有n个ai值,求
1.对于前半部分,因为x的值一定,只需统计 [k*x,(k+1)*x) 的ai的数即可。
2.对于后半部分较为麻烦,显然对于每个x,只需计算比x小的ai。遍历每一个值,利用差分数组来进行统计。
对于任意一个值a来说,在[a,2*a)区间的数,结果为1,ans[a]++,在[2*a,3*a)区间的数结果为2,ans[2*a]++,以此类推。
最后差分数组求和即可获得答案。具体看代码。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <string> #define cla(a, sum) memset(a, sum, sizeof(a)) #define rap(i, m, n) for(int i=m; i<=n; i++) #define rep(i, m, n) for(int i=m; i>=n; i--) #define bug printf("???\n") using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll> P; const int Inf = 0x3f3f3f3f; const double eps = 1e-8; const int mod=998244353; const int maxn = 2e6+5; template <typename T> void read(T &x){ x = 0; int f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();} x *= f; } int n,m; ll cnt[maxn]={0},num[maxn]={0}; ll ans1[maxn]={0},ans2[maxn]={0}; int main() { //ios::sync_with_stdio(false); read(n);read(m); rap(i,1,n){ int c;read(c); cnt[c]++;num[c]++;//记录个数 } rap(i,1,m)cnt[i]+=cnt[i-1]; rap(i,1,m){ int j; for(j=2*i;j<=m;j+=i){//[k*i,(k+1)*i)中的ai的个数*k ans1[i]+=(cnt[j-1]-cnt[j-i-1])*((j-i)/i); } ans1[i]+=(cnt[m]-cnt[j-i-1])*((j-i)/i);//注意ai<=m,要特殊处理 } rap(i,1,m){//利用差分数组 ans2[i]+=num[i]; for(int j=2*i;j<=m;j+=i){ ans2[j]+=num[i]; } } ll ans=0; rap(i,1,m){ ans2[i]+=ans2[i-1];//差分数组不断求和 ans1[i]+=ans2[i];//两者加和 ans=ans^ans1[i]; } cout<<ans; return 0; }
牛客-算式子(思维+差分)
最新推荐文章于 2022-07-24 22:36:13 发布