初探莫队算法

Codeforces 617E题

链接:点击打开链接

题目简介:

      输入n个数,再输入m个询问,以及k。每次询问【L,R】内有多少对l和r,满足从a[l]^.......a[r]=k。

 

    我们想到的第一个解法就是暴力,这就不说了。。

    直接附莫队算法的代码(懒得打字)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1<<20;

int n,m,k,sz;
long long L=1,R=0,Ans=0;

struct node{
	int l,r,id;
}Q[maxn];

int pos[maxn];
long long flag[maxn];//记录每个前缀值的出现次数 
long long ans[maxn];
int a[maxn];//记录初始状态

bool comp(node a,node b)
{
	if(pos[a.l]==pos[b.l]) 
	 return a.r<b.r;
	return pos[a.l]<pos[b.l];
} //首先按块进行排序,如果在同一个块内,则按区间右端点先后排序 

void add(int x)
{
	Ans+=flag[a[x]^k];
	flag[a[x]]++;
}

void del(int x)
{
	flag[a[x]]--;
	Ans-=flag[a[x]^k];
}


int main()
{
	scanf("%d%d%d", &n,&m,&k);
	sz = sqrt(n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d", &a[i]);
		a[i] = a[i]^a[i-1];
		pos[i] = i/sz;
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&Q[i].l,&Q[i].r);
		Q[i].id = i;
	}
	sort(Q+1,Q+1+m,comp);
	flag[0]=1;
	for(int i=1;i<=m;i++)
	{
		while(L<Q[i].l)
		{
			del(L-1);
			L++;
		}
		while(L>Q[i].l)
		{
			L--;
			add(L-1);
		}
		while(R<Q[i].r)
		{
			R++;
			add(R);
		}
		while(R>Q[i].r)
		{
			del(R);
			R--;
		}
		ans[Q[i].id] = Ans;//每个询问的答案 
	}
	for(int i=1;i<=m;i++)
	 cout<<ans[i]<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

总想玩世不恭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值