莫队学习笔记

莫队学习笔记

普通莫队

[P4462] 异或序列

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
struct node{
	int l,r,id;
}q[N];
int n,m,k;
int ans,belongs[N];
int times[N],a[N];
int num[N];
bool cmp(node c,node d){
	int cid=belongs[c.l],did=belongs[d.l];
	if(cid!=did) return cid<did;
	return c.r<d.r;
}
void add(int x){
	ans+=times[a[x]^k];
	times[a[x]]++;
}
void del(int x){
	times[a[x]]--;
	ans-=times[a[x]^k];
}
int main(){
	scanf("%d%d%d",&n,&m,&k);
	int len=sqrt(n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		belongs[i]=(i-1)/len+1;
		a[i]=a[i-1]^a[i];
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&q[i].l,&q[i].r);
		q[i].id=i;
		q[i].l--;
	}
	sort(q+1,q+1+m,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		while(l>q[i].l) add(--l);
		while(r<q[i].r) add(++r);
		while(l<q[i].l) del(l++);
		while(r>q[i].r) del(r--);
		num[q[i].id]=ans;
	}
	for(int i=1;i<=m;i++) printf("%d\n",num[i]); 
}

P2709 小B的询问

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
struct node{
	int l,r,id;
}q[N];
int n,m,k;
int ans,belongs[N];
int times[N],a[N];
int num[N];
bool cmp(node c,node d){
	int cid=belongs[c.l],did=belongs[d.l];
	if(cid!=did) return cid<did;
	return c.r<d.r;
}
void add(int x){
	ans+=2*times[a[x]]+1;
	times[a[x]]++;
}
void del(int x){
	ans-=2*times[a[x]]-1;
	times[a[x]]--;
}
int main(){
	scanf("%d%d%d",&n,&m,&k);
	int len=sqrt(n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		belongs[i]=(i-1)/len+1;
	}
	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,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		while(l>q[i].l) add(--l);
		while(r<q[i].r) add(++r);
		while(l<q[i].l) del(l++);
		while(r>q[i].r) del(r--);
		num[q[i].id]=ans;
	}
	for(int i=1;i<=m;i++) printf("%d\n",num[i]); 
}

P1494 [国家集训队] 小 Z 的袜子

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+7;
struct node{
	int l,r,id;
}q[N];
int n,m,k;
int ans,belongs[N];
int times[N],a[N];
struct node2{
	int a,b;
}num[N];
bool cmp(node c,node d){
	int cid=belongs[c.l],did=belongs[d.l];
	if(cid!=did) return cid<did;
	return c.r<d.r;
}
void add(int x){
	ans+=2*times[a[x]]+1;
	times[a[x]]++;
}
void del(int x){
	ans-=2*times[a[x]]-1;
	times[a[x]]--;
}
signed main(){
	scanf("%lld%lld",&n,&m);
	int len=sqrt(n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		belongs[i]=(i-1)/len+1;
	}
	for(int i=1;i<=m;i++){
		scanf("%lld%lld",&q[i].l,&q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		while(l>q[i].l) add(--l);
		while(r<q[i].r) add(++r);
		while(l<q[i].l) del(l++);
		while(r>q[i].r) del(r--);
		if(q[i].l==q[i].r){
			num[q[i].id]={0,1};continue;
		}
		int temp_fz=ans-(q[i].r-q[i].l+1);
		int temp_fm=(q[i].r-q[i].l+1)*(q[i].r-q[i].l);
		int __=__gcd(temp_fz,temp_fm);
		num[q[i].id]={temp_fz/__,temp_fm/__};
	}
	for(int i=1;i<=m;i++) printf("%lld/%lld\n",num[i].a,num[i].b); 
}

P4137 Rmq Problem / mex

主席树+树上二分做法

#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
const int N=1e7+7;
int n,m;
int cnt,ls[N],rs[N],__[N],lst[N],tot,a[N],root[N];

void modify(int pre,int &k,int l,int r,int x,int val){
	k=++cnt;
	ls[k]=ls[pre],rs[k]=rs[pre];
	if(l==r) return __[k]=val,void();
	if(x<=mid) modify(ls[pre],ls[k],l,mid,x,val);
	else modify(rs[pre],rs[k],mid+1,r,x,val);
	__[k]=min(__[ls[k]],__[rs[k]]);
}

int query(int k,int l,int r,int x){
	if(!k||l==r) return l-1;
	if(__[ls[k]]>=x) return query(rs[k],mid+1,r,x);
	return query(ls[k],l,mid,x);
}

void debug(){
	for(int i=1;i<=n;i++)	printf("%d ",a[i]);
	puts("");
}

int main(){
//	freopen("__.in","r",stdin);
	scanf("%d%d",&n,&m);
	lst[++tot]=0;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),lst[++tot]=a[i],lst[++tot]=a[i]+1;
	}
	sort(lst+1,lst+1+tot);
	tot=unique(lst+1,lst+tot+1)-lst-1;
	for(int i=1;i<=n;i++){
		a[i]=lower_bound(lst+1,lst+1+tot,a[i])-lst;
		modify(root[i-1],root[i],1,tot,a[i],i);
	}
//	debug();
	while(m--){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",query(root[r],1,tot,l));
	}
	return 0;
}

[AHOI2013] 作业

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
#define ll long long 
int n,m,a[N],bl[N],res1[N],res2[N],ans,cnt[N],l,r,len,qcnt[N],tot[N];
struct node{
	int l,r,a,b,id;
}q[N];
bool cmp(node a, node b){
	if(bl[a.l]==bl[b.l])return a.r<b.r;
	return bl[a.l]<bl[b.l];
}
void add(int x){
	cnt[x]++,qcnt[bl[x]]++;
	if(cnt[x]==1)tot[bl[x]]++;
}
void del(int x){
	cnt[x]--,qcnt[bl[x]]--;
	if(!cnt[x])tot[bl[x]]--;
}
void getans(node q){
	int lid=bl[q.a],rid=bl[q.b];
	if(lid==rid){
		for(int i=q.a;i<=q.b;i++){
			res1[q.id]+=cnt[i];
			if(cnt[i])res2[q.id]++;
		}
		return;
	}
	for(int i=q.a;bl[i]==bl[q.a];i++){
		res1[q.id]+=cnt[i];
		if(cnt[i])res2[q.id]++;
	}
	for(int i=lid+1;i<=rid-1;i++){
		res1[q.id]+=qcnt[i];
		res2[q.id]+=tot[i];
	}
	for(int i=q.b;bl[i]==bl[q.b];i--){
		res1[q.id]+=cnt[i];
		if(cnt[i])res2[q.id]++;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	len=sqrt(n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),bl[i]=(i-1)/len+1;
	for(int i=1;i<=m;i++)scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b),q[i].id=i;
	sort(q+1,q+m+1,cmp);
	l=1,r=0,ans=0;
	for(int i=1;i<=m;i++){
		while(l>q[i].l)add(a[--l]);
		while(r<q[i].r)add(a[++r]);
		while(l<q[i].l)del(a[l++]);
		while(r>q[i].r)del(a[r--]);
		getans(q[i]);
	}
	for(int i=1;i<=m;i++)printf("%d %d\n",res1[i],res2[i]);
	return 0;
} 
posted @ 2023-07-21 16:01  Zimo_666  阅读(8)  评论(0编辑  收藏  举报