注意:
- 前缀和的缘故,q[i].l 需要减减。
- 因为pre[l - 1] ^ pre[r] = k,所以pre[r] ^ k = pre[l - 1]
- (a[1] ^ a[2] ^ … ^ a[10]) ^ (a[1] ^ a[2] ^ … ^ a[5]) = a[6] ^ a[7] ^ … ^ a[10]
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const ll maxll = -1u>>1;
const ll inf = 0x3f3f3f3f;
const ll maxn = 2e6 + 10;
ll pos[maxn],vis[maxn],Ans[maxn],pre[maxn];
ll n,m,k,ans;
struct Query{
ll l, r, id;
}Q[maxn];
bool cmp(Query a, Query b){
if(pos[a.l] == pos[b.l])
return a.r < b.r;
else
return pos[a.l] < pos[b.l];
}
void add(ll pos){
ans += vis[pre[pos]^k];
vis[pre[pos]] ++;
}
void del(ll pos){
vis[pre[pos]] --;
ans -= vis[pre[pos]^k];
}
int main() {
cin>>n>>m>>k;
ll sz = sqrt(n);
for(ll i=1;i<=n;i++){
cin>>pre[i];
pre[i] = pre[i] ^ pre[i - 1];
pos[i] = i / sz;
}
for(ll i=1;i<=m;i++){
cin>>Q[i].l>>Q[i].r;
Q[i].l --;
Q[i].id = i;
}
sort(Q+1, Q+1+m, cmp);
ll L=1, R=0;
for(ll i=1;i<=m;i++){
while(L < Q[i].l) del(L ++);
while(L > Q[i].l) add(-- L);
while(R < Q[i].r) add(++ R);
while(R > Q[i].r) del(R --);
Ans[Q[i].id] = ans;
}
for(ll i=1;i<=m;i++){
cout<<Ans[i]<<endl;
}
return 0;
}
注意:
- 注释的重载运算符排序写反了,后边两端注释是对的。
- 数学上边稍微化简一下,a[1](a[1]-1) + a[2](a[2]-1)+…+a[n]*(a[n]-1) = a[1]平方+a[2]平方 + …+ a[n]平方 - (a[1] + a[2] + … + a[n]),且a[1] + a[2] +…+a[n] == len == R - L + 1
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 5e4 + 10;
int pos[maxn],a[maxn];
ll AnsFZ[maxn],vis[maxn],AnsFM[maxn];
ll n,m,temp;
int L = 1, R = 0;
ll GCD(ll a,ll b){return b==0?a:GCD(b,a%b);}
struct Query{
int l, r, id;
}q[maxn];
bool cmp(Query a, Query b){
if(pos[a.l] == pos[b.l])
return a.r < b.r;
else
return pos[a.l] < pos[b.l];
}
inline int getlen(Query a){
return a.r - a.l + 1;
}
void add(int x)
{
temp -= vis[x]*vis[x];
vis[x]++;
temp += vis[x]*vis[x];
}
void del(int x)
{
temp -= vis[x]*vis[x];
vis[x]--;
temp += vis[x]*vis[x];
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int sz = sqrt(n);
for(int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id = i;
pos[i] = i / sz;
}
sort(q + 1, q + 1 + m, cmp);
for(int i=1;i<=m;i++){
while(R < q[i].r) add(a[++R]);
while(R > q[i].r) del(a[R--]);
while(L < q[i].l) del(a[L++]);
while(L > q[i].l) add(a[--L]);
int len = getlen(q[i]);
ll fenzi = temp - len;
ll fenmu = (ll)len * (len - 1);
ll gcd = GCD(fenzi,fenmu);
AnsFZ[q[i].id] = fenzi / gcd;
AnsFM[q[i].id] = fenmu / gcd;
if(!fenzi)
AnsFM[q[i].id] = 1;
}
for(int i=1;i<=m;i++)
printf("%lld/%lld\n",AnsFZ[i],AnsFM[i]);
return 0;
}