莫队学习笔记
莫队学习笔记
普通莫队
[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;
}