列表

详情


NC235473. AIR Triplet

描述

翼人的诅咒早就在第一千个夏天被打破了,所以化作名为 Air 的乌鸦的往人就不需要再想这个问题了,开始致力于解决困扰人们多年的 3-SUM 问题。但是 3-SUM 问题很困难,所以他希望能解决 3-AIR 问题。

小 L 定义对于三元组 (i,j,k),如果其满足 (其中 为按位异或),那么我们称其为 3-AIR 三元组。你除了要求出有多少 3-AIR 三元组,还需要面临一些单点修改。

具体而言,您面临的问题是:现在有一个长 n 的序列 a,有 m 次操作,每次操作给定 x,y,你需要将 a_x 修改为 y,然后对于每次修改输出修改完的数列中,有多少对 (i,j,k) 满足 ,其中 为按位异或。

输入描述

第一行两个正整数 n,m

接下来一行 n 个正整数,代表序列 a

后面 m 行每行两个正整数代表 x,y

输出描述

m 行,每行代表一次修改后的答案。

示例1

输入:

4 2
1 2 3 1
2 1
3 1

输出:

1
4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 46ms, 内存消耗: 6008K, 提交时间: 2022-04-30 21:07:47

#include<bits/stdc++.h>
using namespace std;
int a[300005],b[1000005];
int main(){
	int t,n,m,i,x,y;
	long long s=0,p;
	memset(b,0,sizeof b);
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){
		scanf("%d",&a[i]);
		b[a[i]]++;
	}
	for(i=1;i<=1000000;i++){
		p=b[i];
		s+=p*(p-1)*(p-2)/2/3;
	}
	while(m--){
		scanf("%d%d",&x,&y);
		p=b[a[x]];
		s-=3*(p-1)*(p-2)/2/3;
		b[a[x]]--;
		a[x]=y;
		b[a[x]]++;
		p=b[a[x]];
		s+=3*(p-1)*(p-2)/2/3;
		printf("%lld\n",s);
	}
}

Python3 解法, 执行用时: 778ms, 内存消耗: 17728K, 提交时间: 2022-05-28 13:47:16

n,m=map(int,input().split(' '))
a=[0]+list(map(int,input().split(' ')))
arr=[0]*(10**6+1)
ans=0
for i in range(1,n+1):
    arr[a[i]]+=1
for item in arr:
    if item>=3:
        ans+=item*(item-1)*(item-2)//6
for i in range(m):
    x,y=map(int,input().split(' '))
    arr[y]+=1
    arr[a[x]]-=1
    if a[x]!=y:
        ans += (arr[y] - 1) * (arr[y] - 2) // 2
        ans -= (arr[a[x]]) * (arr[a[x]] - 1) // 2
    a[x] = y
    print(ans)

上一题