首页 > 其他分享 >P4462 [CQOI2018]异或序列

P4462 [CQOI2018]异或序列

时间:2024-10-22 14:33:51浏览次数:7  
标签:cnt ch xor text LL P4462 异或 CQOI2018

[CQOI2018]异或序列

题目描述

已知一个长度为n的整数数列\(a_1,a_2,...,a_n\),给定查询参数l、r,问在\(a_l,a_{l+1},...,a_r\)区间内,有多少子序列满足异或和等于k。也就是说,对于所有的x,y (I ≤ x ≤ y ≤ r),能够满足\(a_x \bigoplus a_{x+1} \bigoplus ... \bigoplus a_y = k\)的x,y有多少组。

对于30%的数据,\(1 ≤ n, m ≤ 1000\)

对于100%的数据,\(1 ≤ n, m ≤ 10^5, 0 ≤ k, a_i ≤ 10^5,1 ≤ l_j ≤ r_j ≤ n\)

分析

\(\text{异或是一个神奇的运算符号!}\)

$\text{由}\ a \ xor \ b= c\ \text{ 可得 } \ \ c \ xor \ b= a\ \text{ 和 }\ c \ xor \ a= b\ $

\(\text{且 } a\ xor \ a =0 \ ,a\ xor\ 0=a\)

\(\text{我们设 }sum_i=\left[1,i\right]\text{ 的异或和}\)

$\text{所以一个区间 }\left[l,r\right]\text{ 的异或和为 }k $

\(\text{那么 }sum_{r}\ xor\ sum_{l-1}= k\ \ ,\ \ \ sum_r \ xor\ k=sum_{l-1}\)

\(\text{再加上}\)我们都学过的\(\text{莫队就轻松解决了}\)

Code:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define Ld long double
const int N=2e6;

LL n,m,a[N],sq,l=1,r=0,now,ans[N],xo[N],la,k,cnt[N];//cnt为此时区间内以i为异或值的区间数
struct node{
    LL l,r,id,bel;
}t[N];

inline LL read(){
    LL s=0,w=1;char ch;
    ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-'){w=-1;}ch=getchar();}
    while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*w;
}

void print(LL x){
    char F[200];LL cnt=0;
    if(x<0) {x=-x;putchar('-');}
    if(x==0){putchar('0');putchar('\n');return ;}
    while(x){F[++cnt]=x%10;x/=10;}
    while(cnt){putchar(F[cnt--]+'0');}
    putchar('\n');
    return ;
}

bool cmp(node a, node b){
    return (a.bel^b.bel)?a.bel<b.bel:((a.bel&1)?a.r<b.r:a.r>b.r);
}

void del(LL pos){
    --cnt[xo[pos]];//因为这个点要删了,所以区间内以此异或值结尾的区间数减1
    now-=cnt[xo[pos]^k];
    return ;
}
/*关于为什么del要先减再算答案
  因为当k=0时,他自己也算进去了所以要先减
  add同理  
*/
void add(LL pos){
    now+=cnt[xo[pos]^k];
    cnt[xo[pos]]++;
    return ;
}

int main(){
    n=read(),m=read(),k=read();
    sq=sqrt(n);
    for(int i=1;i<=n;i++){
        xo[i]=read();
        xo[i]=xo[i-1]^xo[i];
    }
    for(int i=1;i<=m;i++){
        t[i].l=read()-1;
        t[i].r=read();
        t[i].id=i;
        t[i].bel=(t[i].l-1)/sq+1;
    }
    sort(t+1,t+1+m,cmp);
    for(int i=1;i<=m;i++){
        LL lt=t[i].l,rt=t[i].r;
        while(l<lt) del(l++);
        while(l>lt) add(--l);
        while(r<rt) add(++r);
        while(r>rt) del(r--);
        ans[t[i].id]=now;
    }
    for(int i=1;i<=m;i++){
        print(ans[i]);
    }
    return 0;
}


双倍经验

发布时间:2022-06-08 13:05

标签:cnt,ch,xor,text,LL,P4462,异或,CQOI2018
From: https://www.cnblogs.com/xingke233/p/18492665

相关文章

  • 洛谷题单指南-字符串-P4735 最大异或和
    原题链接:https://www.luogu.com.cn/problem/P4735题意解读:已知长度为n的数组a[],要在l~r范围找到一个p,使得a[p]^a[p+1]^...^a[n]^x最大,求这个最大的异或值。解题思路:1、利用前缀和将问题转化设s[]是a[]的前缀异或数组,要计算a中一段范围l~r的异或,可以借助于s由于s[r]=a[0]^a[......
  • B. 异或(xor)
    B.异或(xor)题意给你\(n\)个数,你可以执行若干次操作,每次选择一个区间异或上一个数,问最少操作次数使得所有数变成\(0\),输出最小的操作次数。\(n\le17,a_i\le10^8\)solution居然还有异或差分这种思想,是我孤陋寡闻了因为是区间操作,所以我们考虑在异或差分序列上操作。显......
  • 【题解】P3917 异或序列
    传送门也算是一个有关于异或的小trick吧,简单记录一下。可以维护原序列的前缀异或和\(sum\),于是原题答案贡献变为\(\sum\limits_{i=1}^n\sum\limits_{j=i}^nsum_j\oplussum_{i-1}\)。变形一下为\(\sum\limits_{i=0}^{n-1}\sum\limits_{j=1}^{i+1}sum_i\oplussum_{j}......
  • 洛谷题单指南-字符串-P5283 [十二省联考 2019] 异或粽子
    原题链接:https://www.luogu.com.cn/problem/P5283题意解读:n个整数,每次从从取l~r的数进行异或得到美味值,一共取k次,并计算这k个美味值之和的最大值。解题思路:1、如何O(1)的计算l~r数的异或,得到美味值可以借助前缀和思想,a[i]为第i个数,s[i]表示a[1]~a[i]每个数的异或值,要计算l~r的......
  • Codeforces Round 316 (Div. 2) D题 Tree Requests(二分,dfs,在线,前缀异或)
    题目链接CodeforcesRound316(Div.2)D题TreeRequests思路将262626个字母全部当作一个二进制数。将每个深度的结点按照dfs序放到一个vector里,同时记录每个vector......
  • 题解:P11008 『STA - R7』异或生成序列
    Solution序列\(p\)是\(1\)~\(n\)的排列,因此考虑搜索回溯。由\(\sumn\le2\times10^6\)得知\(O(n^2)\)会炸,深感遗憾但仍考虑剪枝。坚信深搜过百万的蒟蒻。。。原\(b\)序列为长度\(n-1\)的序列:{\(b_1,b_2,b_3\cdotsb_n-1\)}将其前面插入一个元素\(......
  • 使用异或操作实现字符串加密与解密
    异或加密是一种简单而有效的加密技术,它的特点是同一密钥可用于加密和解密,以下是一个例子:usingSystem;usingSystem.Text;publicstaticclassEncryption{///<summary>///bytes数据通过encryptCode进行异或(加密|解密)///将传入的bytes作为返回值,不再额外分......
  • CF2014H Robin Hood Archery(异或哈希)
    题目链接题意Alice和Bob将进行一场射击比赛题解点击查看代码#include<bits/stdc++.h>usingi64=longlong;i64seed=std::chrono::high_resolution_clock::now().time_since_epoch().count();std::mt19937_64rng(seed^std::random_device{}());constexp......
  • [CL-22] 异或和之和
    CL-22二进制拆分。对于枚举到的每一个二进制位\(i\),注意到其对答案的贡献只有\(0\)和\(2^{i}\)两种情况考虑什么时候贡献是\(2^i\),可以发现,当选入奇数个该位为\(1\)的数之后,对答案的贡献是\(2^{i}\)因此变成求选出奇数个为\(1\)的数的方案数设该位为\(1\)的数有......
  • 题解:P10104 [GDKOI2023 提高组] 异或图
    \(\text{Link}\)本题属于集合划分容斥,更多关于集合划分容斥的信息可观看详细揭秘:集合划分容斥的容斥系数。题意给定一个\(n\)个点\(m\)条边的图以及一个长为\(n\)的序列\(a_{1\dotsn}\),有一常数\(C\),你需要求出有多少序列\(b_{1\dotsn}\)满足\(0\leb_i\lea_i\)......