几种简单莫队

大概   我现在 能叫的出名字的莫队 大概有

普通莫队  带修莫队 回滚莫队 树上莫队  树上带修莫队 (可能还有些奇怪的莫队姿势 但是 现在还没学到orz  树上莫队  等几天填坑

莫队入门http://www.lydsy.com/JudgeOnline/problem.php?id=2038

/**************************************************************
    Problem: 2038
    User: wang9897
    Language: C++
    Result: Accepted
    Time:828 ms
    Memory:3648 kb
****************************************************************/
 
#include <bits/stdc++.h>
#define N 50005
#define ll long long 
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
ll num[N],ans[N],p[N];
ll ans1[N];
int a[N],size;
ll _gcd(ll x,ll y){ 
    if(y==0) return x; 
    else return(_gcd(y,x%y)); 
}
typedef struct node{
    int l,r,biao;
    friend bool operator<(node aa,node bb){
        if(p[aa.l]==p[bb.l]) return aa.r<bb.r;
        return p[aa.l]<p[bb.l]; 
    }
}node;
node d[N];
int main(){
    ios::sync_with_stdio(false);
    int n,m;scanf("%d%d",&n,&m);
    size=(int)sqrt(n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        p[i]=(i-1)/size+1;
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&d[i].l,&d[i].r);
        d[i].biao=i;
    }
    sort(d+1,d+m+1);
    int L=1;int R=0;ll sum=0;
    for(int i=1;i<=m;i++){
        while(R>d[i].r){
            sum-=(num[a[R]]-1);num[a[R]]--;
            R--;
        }
        while(R<d[i].r){
            R++;sum+=num[a[R]];num[a[R]]++;
        }
        while(L>d[i].l){
            L--;sum+=num[a[L]];num[a[L]]++;
        }
        while(L<d[i].l){
            sum-=(num[a[L]]-1);num[a[L]]--;
            L++;
        }
        if(sum==0){
            ans[d[i].biao]=0;ans1[d[i].biao]=1;
        }
        else{
        ll len=d[i].r-d[i].l+1;
        len=len*(len-1)/2;
        ll gcd=_gcd(sum,len);
        ans[d[i].biao]=sum/gcd;ans1[d[i].biao]=len/gcd;}
    }
    for(int i=1;i<=m;i++){
        printf("%lld/%lld\n",ans[i],ans1[i]);
    }
    return 0;
}

 带修莫队http://www.lydsy.com/JudgeOnline/problem.php?id=2120

/**************************************************************
    Problem: 2120
    User: c20161007
    Language: C++
    Result: Accepted
    Time:996 ms
    Memory:5540 kb
****************************************************************/
 
#include <bits/stdc++.h>
#define ll long long
#define N 10005
#define M 1000005
using namespace std;
ll readll(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int readint(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int p[N],a[N],num[M],b[N];
typedef struct node{
    int l,r,t,biao;
    friend bool operator <(node aa,node bb){
        if(p[aa.l]==p[bb.l]&&aa.r==bb.r) return aa.t<bb.t;
        else if(p[aa.l]==p[bb.l]) return aa.r<bb.r;
        return p[aa.l]<p[bb.l];
    }
}node;
node d[N];
typedef struct List{
    int pos,vul;
}List;
List d1[1005],d2[1005];
int ans[N];
int n,m,size,cnt,sum;
void jiaru(int l,int r,int t){
    if(d1[t].pos>=l&&d1[t].pos<=r){
        num[a[d1[t].pos]]--;
        if(num[a[d1[t].pos]]==0) sum--;
        if(num[d1[t].vul]==0) sum++;
        num[d1[t].vul]++;
    }
    a[d1[t].pos]=d1[t].vul;
}
void shanchu(int l,int r,int t){
    if(d2[t].pos>=l&&d2[t].pos<=r){
        num[a[d2[t].pos]]--;
        if(num[a[d2[t].pos]]==0) sum--;
        if(num[d2[t].vul]==0) sum++;
        num[d2[t].vul]++;
    }
    a[d2[t].pos]=d2[t].vul;
}
int main(){
    ios::sync_with_stdio(false);cnt=0;
    n=readint();m=readint();size=(int)pow(n,2.0/3);
    for(int i=1;i<=n;i++){
        a[i]=readint();p[i]=(i-1)/size+1;
        b[i]=a[i];
    }
    char ch;int l,r;int u=0;
    for(int i=1;i<=m;i++){
        scanf(" %c",&ch);l=readint();r=readint();ans[i]=-1;
        if(ch=='Q'){
            d[++u].l=l;d[u].r=r;d[u].t=cnt;d[u].biao=i;
        }
        else{
            cnt++;d1[cnt].pos=l;d1[cnt].vul=r;
            d2[cnt].pos=l;d2[cnt].vul=b[l];
            b[l]=r;
        }
    }
    sort(d+1,d+u+1);
    int L=1,R=0,T=0;sum=0;
    for(int i=1;i<=u;i++){
        while(T>d[i].t){
            shanchu(L,R,T);T--;
        }
        while(T<d[i].t){
            T++;jiaru(L,R,T);
        }
        while(R>d[i].r){
            num[a[R]]--;
            if(num[a[R]]==0) sum--;
            R--;
        }
        while(R<d[i].r){
            R++;
            if(num[a[R]]==0) sum++;
            num[a[R]]++;
        }
        while(L>d[i].l){
            L--;
            if(num[a[L]]==0) sum++;
            num[a[L]]++;
        }
        while(L<d[i].l){
            num[a[L]]--;
            if(num[a[L]]==0) sum--;
            L++;
        }
        ans[d[i].biao]=sum;
    }
    for(int i=1;i<=m;i++){
        if(ans[i]==-1) continue;
        printf("%d\n",ans[i]);
    }
    return 0;
}

  回滚莫队http://www.lydsy.com/JudgeOnline/problem.php?id=4241

#include <bits/stdc++.h>
#define ll long long
#define N 100005
using namespace std;
ll readll(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int readint(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
int p[N],a[N],num[N],n,m,size,num1[N];
ll sum;
vector<ll>vec;
typedef struct node{
	int l,r,biao;
	friend bool operator <(node aa,node bb){
		if(p[aa.l]==p[bb.l]) return aa.r<bb.r;
		return p[aa.l]<p[bb.l];
	}
}node;
node d[N];
int cnt[505];
ll ans[N];
int main(){
	ios::sync_with_stdio(false);
	n=readint();m=readint();size=(int)sqrt(n);
	for(int i=1;i<=n;i++){
		a[i]=readint();p[i]=(i-1)/size+1;vec.push_back(a[i]);
	}
	sort(vec.begin(),vec.end());
	int t=unique(vec.begin(),vec.end())-vec.begin();
	for(int i=1;i<=n;i++) a[i]=lower_bound(vec.begin(),vec.begin()+t,a[i])-vec.begin()+1;
	int l,L,r;
	for(int i=1;i<=m;i++) d[i].l=readint(),d[i].r=readint(),cnt[(d[i].l-1)/size+1]++,d[i].biao=i;
	sort(d+1,d+m+1);int u=1;ll sum,sum1;
	for(int i=1;i<=p[n];i++){
		if(!cnt[i]) continue;L=l=min(n,size*i)+1;r=l-1;sum=-1;
		while(p[d[u].l]<=i){
			if(p[d[u].l]==p[d[u].r]){
				sum=-1;
				for(int j=d[u].l;j<=d[u].r;j++){
					num1[a[j]]++;sum=max(sum,1ll*num1[a[j]]*vec[a[j]-1]);
				}
				for(int j=d[u].l;j<=d[u].r;j++) num1[a[j]]=0;
				ans[d[u].biao]=sum;sum=-1;u++;
				if(u>m||p[d[u].l]>i) break;
				continue;
			}
			while(r<d[u].r){
				r++;num[a[r]]++;sum=max(sum,1ll*num[a[r]]*vec[a[r]-1]);
			}
			sum1=sum;
			while(L>d[u].l){
				L--;			
				num[a[L]]++;sum=max(sum,1ll*num[a[L]]*vec[a[L]-1]);
			}
			L=l;
			while(L>d[u].l){
				L--;num[a[L]]--;
			}
			L=l;ans[d[u].biao]=sum;sum=sum1;
			u++;
			if(u>m) break;
		}
		if(u>m) break;
		for(int j=1;j<=n;j++) num[a[j]]=0;
	}
	for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
	return 0;
}

  //大概今天的莫队 就到这里了 

posted @ 2018-02-12 21:04  wang9897  阅读(166)  评论(0编辑  收藏  举报