IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> P4887-[模板]莫队二次离线(第十四分块(前体)) -> 正文阅读

[数据结构与算法]P4887-[模板]莫队二次离线(第十四分块(前体))

正题

题目链接:https://www.luogu.com.cn/problem/P4887


题目大意

给出一个长度为 n n n的序列 a a a m m m次询问 [ l , r ] [l,r] [l,r]求有多少个 l ≤ i < j ≤ r l\leq i< j\leq r li<jr满足 a i ? x o r ? a j a_i\ xor\ a_j ai??xor?aj?二进制下恰好有 k k k 1 1 1

1 ≤ n , q ≤ 1 0 5 , 0 ≤ a i , k < 2 14 1\leq n,q\leq 10^5,0\leq a_i,k<2^{14} 1n,q105,0ai?,k<214


解题思路

f ( x , i ) f(x,i) f(x,i)表示 1 ~ i 1\sim i 1i中有多少个 a a a a x a_x ax?满足条件,假设我们已经知道了区间 [ l , r ] [l,r] [l,r]的答案,以 [ l , r ] → [ l , r + 1 ] [l,r]\rightarrow [l,r+1] [l,r][l,r+1]为例,答案会增加 f ( r + 1 , r ) ? f ( r + 1 , l ? 1 ) f(r+1,r)-f(r+1,l-1) f(r+1,r)?f(r+1,l?1) f ( r + 1 , r ) f(r+1,r) f(r+1,r)我们可以直接预处理出每个。

至于 f ( r + 1 , l ? 1 ) f(r+1,l-1) f(r+1,l?1)我们发现我们的桶和 f ( x , i ) f(x,i) f(x,i)中的 i i i也就是 l ? 1 l-1 l?1有关,在 r r r移动的过程中 l ? 1 l-1 l?1是不变的,所以我们可以将 r → r + k r\rightarrow r+k rr+k这个过程离线下来,在指针枚举 l ? 1 l-1 l?1时统一处理。

其他指针的移动一样处理即可。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const ll N=1e5+10,L=1<<14,T=316;
struct node{
	ll l,r,id;
}q[N];
ll n,m,k,c[L],v[L],pre[N],a[N],s[N],ans[N];
vector<int> b;
vector<node> u[N];
bool cmp(node x,node y)
{return (x.l/T==y.l/T)?(x.r<y.r):(x.l/T<y.l/T);}
signed main()
{
	scanf("%lld%lld%lld",&n,&m,&k);
	for(ll i=1;i<L;i++)c[i]=c[i-(i&-i)]+1;
	for(ll i=0;i<L;i++)
		if(c[i]==k)b.push_back(i);
	if(k>14){
		for(ll i=1;i<=m;i++)
			puts("0");
		return 0;
	}
	for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(ll i=1;i<=n;i++){
		pre[i]=v[a[i]];
		for(ll j=0;j<b.size();j++)
			v[a[i]^b[j]]++;
	}
	for(ll i=1,l,r;i<=m;i++){
		scanf("%lld%lld",&q[i].l,&q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp);
	ll l=1,r=0;
	for(ll i=1;i<=m;i++){
		if(l<q[i].l)u[r].push_back((node){l,q[i].l-1,-i});
		while(l<q[i].l)s[i]+=pre[l],l++;
		if(l>q[i].l)u[r].push_back((node){q[i].l,l-1,i});
		while(l>q[i].l)l--,s[i]-=pre[l];
		if(r<q[i].r)u[l-1].push_back((node){r+1,q[i].r,-i});
		while(r<q[i].r)r++,s[i]+=pre[r];
		if(r>q[i].r)u[l-1].push_back((node){q[i].r+1,r,i});
		while(r>q[i].r)s[i]-=pre[r],r--;
	}
	memset(v,0,sizeof(v));
	for(ll i=1;i<=n;i++){
		for(ll j=0;j<b.size();j++)
			v[a[i]^b[j]]++;
		for(ll j=0;j<u[i].size();j++){
			for(ll x=u[i][j].l;x<=u[i][j].r;x++){
				ll tmp=v[a[x]];
				if(k==0&&x<=i)tmp--;
				if(u[i][j].id>0)s[u[i][j].id]+=tmp;
				else s[-u[i][j].id]-=tmp;
			}
		}
	}
	for(ll i=1;i<=m;i++)
		s[i]+=s[i-1],ans[q[i].id]=s[i];
	for(ll i=1;i<=m;i++)
		printf("%lld\n",ans[i]);
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:44:27  更:2022-05-05 11:47:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:42:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码