首页 > 其他分享 >P4462 题解

P4462 题解

时间:2024-04-08 13:23:41浏览次数:18  
标签:pre tmp cnt xor int 题解 P4462 bigoplus

题目传送门

请确保您接触过莫队再阅读此文:

对于所有询问,和普通莫队一样的分块然后排序。在这里只讨论 adddel 操作的具体实现。

题目中需要求一段区间的异或值,所以我们可以预处理序列 \(a\) 的“前缀异或值”pre_xor,题目中的 \(a_x \bigoplus a_{x+1} \bigoplus \dots \bigoplus a_y\) 可利用异或的性质转化为 pre_xor[y] ^ pre_xor[x - 1]

这样,求区间 \([l,r]\) 中能够满足 \(a_x \bigoplus a_{x+1} \bigoplus \dots \bigoplus a_y = k\) 的 \(x,y\) 有多少组,就相当于求区间 \([l - 1,r]\) 中有多少组 pre_xor[y] ^ pre_xor[x - 1] == k。这就可以用莫队了。

显然,设 cnt[x] 代表数 \(x\) 的出现次数,则其可以与所有的 \(x \bigoplus k\) 配对即可。显然,在这里的 \(x\) 和 \(x \bigoplus k\) 一般是不用担心顺序的,总贡献为 cnt[x] * cnt[x ^ k]

不过有一个特殊情况:当 \(k = 0\) 时,\(x = x \bigoplus k\),这个时候就得特判贡献为 (cnt[x] * (cnt[x] - 1)) >> 1 了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 9,M = 1e5 + 9,SqrtN = 339,K = 1 << 20;
int n,m,k;
struct block{
	int l,r;
} b[SqrtN];
int belong[N];
int block_len,block_cnt;
void build_block(){
	block_len = block_cnt = (int)sqrt(n);
	for(int i = 1;i <= block_cnt;i++){
		b[i].l = b[i - 1].r + 1;
		b[i].r = i * block_len;
	}
	b[block_cnt].r = n;
	for(int i = 1;i <= block_cnt;i++)
		for(int j = b[i].l;j <= b[i].r;j++)
			belong[j] = i;
}
struct queries{
	int l,r,id;
} q[M];
int a[N],pre_xor[N];
int cnt[K];
int ans[M],tmp;
int lres = 1,rres;
bool cmp(queries q1,queries q2){
    return belong[q1.l] == belong[q2.l] ? belong[q1.r] < belong[q2.r] : belong[q1.l] < belong[q2.l];
}
void add(int x){
	//tmp -= cnt[x] * (k ? cnt[x ^ k] : (cnt[x] - 1));
	tmp -= k ? (cnt[x] * cnt[x ^ k]) : ((cnt[x] * (cnt[x] - 1)) >> 1);
	cnt[x]++;
	//tmp += cnt[x] * (k ? cnt[x ^ k] : (cnt[x] - 1));
	tmp += k ? (cnt[x] * cnt[x ^ k]) : ((cnt[x] * (cnt[x] - 1)) >> 1);
}
void del(int x){
	//tmp -= cnt[x] * (k ? cnt[x ^ k] : (cnt[x] - 1));
	tmp -= k ? (cnt[x] * cnt[x ^ k]) : ((cnt[x] * (cnt[x] - 1)) >> 1);
	cnt[x]--;
	//tmp += cnt[x] * (k ? cnt[x ^ k] : (cnt[x] - 1));
	tmp += k ? (cnt[x] * cnt[x ^ k]) : ((cnt[x] * (cnt[x] - 1)) >> 1);
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> m >> k;
	build_block();
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		pre_xor[i] = pre_xor[i - 1] ^ a[i];
	}
	for(int i = 1;i <= m;i++){
		cin >> q[i].l >> q[i].r;
		q[i].id = i;
	}
	sort(q + 1,q + m + 1,cmp);
    for(int i = 1;i <= m;i++){
        int L = q[i].l - 1,R = q[i].r;
        while(lres > L)
            add(pre_xor[--lres]);
        while(rres < R)
            add(pre_xor[++rres]);
        while(lres < L)
            del(pre_xor[lres++]);
        while(rres > R)
            del(pre_xor[rres--]);
        ans[q[i].id] = tmp;
    }
	for(int i = 1;i <= m;i++)
		cout << ans[i] << '\n';
	return 0;
}

标签:pre,tmp,cnt,xor,int,题解,P4462,bigoplus
From: https://www.cnblogs.com/5002-qwq/p/18120911

相关文章

  • ABC348G题解
    令\(f_i\)为当\(k=i\)时的答案。令\(g_i\)为\(f_i+\max\limits_{j\inS}b_j\)。也就是不减去\(b\)的最大值的结果。直接做是\(O(n^2)\)的,考虑分治,令两个子问题的\(f,g\)分别为\(fl,gl\)和\(fr,gr\)。合并的时候做一个\[f_i=\max(\max\limits_{c+d=i}(gl_c+fr......
  • 蓝桥杯嵌入式2023年第十四届省赛主观题解析
    1 题目2 代码/*Includes------------------------------------------------------------------*/#include"main.h"#include"adc.h"#include"rtc.h"#include"tim.h"#include"gpio.h"/*Privateinclud......
  • Hetao P1178 冒险者 题解 [ 绿 ][ 最短路 ][ 线性 dp ]
    原题题解本蒟蒻采用的和大部分人解法不同,是根据当前标记值的总和跑最短路的一种解法。思路30min,调代码2h的我太蒻了首先观察题面可以发现本题求的是最少操作数,由于要求最小且有变化的过程,所以可以使用dp求解,也可以使用最短路算法求解,本篇先介绍最短路的算法。其实......
  • ABC218E Destruction题解
    ABC218EDestruction题解题意给你一个\(n\)个点\(m\)条边的带权无向联通图,你可以删去任意条边,要求保证图联通的情况下删去边的权值和最大。\((n\le2\cdot10^5\,\m\le2\cdot10^5\,\-10^9\lee_i\le10^9)\)(\(e_i\)为边权)分析首先我们考虑边权全为正的情况,那么我们删......
  • 【解题报告】RbOI Round 1,A&D题解
    【RbOIR1】A&D题解其他题题解请移步B、C点击图片跳转比赛:A.AnxiousRobin从左到右扫一遍,按照题意模拟即可。这里解释一下我的代码:因为只判断了六种字母,所以遇到-会直接过滤,无需特判。展开代码#include<bits/stdc++.h>#definelllonglong#defineMyWifeCrista......
  • 图的遍历试题解析
    一、单项选择题01.下列关于广度优先算法的说法中,正确的是(A ).Ⅰ.当各边的权值相等时,广度优先算法可以解决单源最短路径问题Ⅱ.当各边的权值不等时,广度优先算法可用来解决单源最短路径问题Ⅲ.广度优先遍历算法类似于树中的后序遍历算法Ⅳ.实现图的广度优先算法时,使用的......
  • 关于layui的单图片上传遇坑-field-input-name问题解决
    直接上代码注意field:'ymftimage'layui.use(function(){varupload=layui.upload;varlayer=layui.layer;varelement=layui.element;var$=layui.$;//单图片上传varuploadInst=upload.render({elem:'#ID-upload-demo-btn',......
  • ARC175 A~C 题解
    ARC175ASpoonTakingProblem题目大意有\(n\)个人围成一个环,第\(i\)个人左手边是第\(i\)个勺子,右手边是第\(i\%n+1\)个勺子。每个人的惯用手用一个字符\(a_i=\)L/R/?表示,即左手/右手/未知。给定\(1\simn\)的一个排列\(P_1,\dots,P_n\)表示这\(n\)个人行动的......
  • 货币系统—背包问题—python题解
    题目链接:货币系统题目描述:给定V种货币(单位:元),每种货币使用的次数不限。不同种类的货币,面值可能是相同的。现在,要你用这V种货币凑出N元钱,请问共有多少种不同的凑法。输入格式第一行包含两个整数V和N。接下来的若干行,将一共输入V个整数,每个整数表示一种货币的......
  • 5G网络建设【华为OD机试】(JAVA&Python&C++&JS题解)
    一.题目-5G网络建设现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站,编号固定为1到N,接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通,不同基站之间架设光纤的成本各不相同,且有些节点之间已经存在光纤相连,请你设计算法,计算出能联通这些基站的最小成本是......