• [学习笔记]莫队


    补充:戳这里

    1、NPY and girls

    题意简述:给定一个长度为 (n) 的序列,每次给定一个区间 ([l,r]),求 ((r-l+1)!/(count(1)! imes count(2)! imes ... imes count(n)!))

    先预处理出阶乘和阶乘的乘法逆元,然后每次更新除掉原来的数乘上后来的数就好了

    (Code Below:)

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int maxn=30000+10;
    const int p=1e9+7;
    int n,m,a[maxn],cnt[maxn],ans[maxn],farc[maxn],inv[maxn],blo,now;
    
    struct Query{
    	int l,r,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
    	if((a.l-1)/blo!=(b.l-1)/blo)
    		return (a.l-1)/blo<(b.l-1)/blo;
    	return a.r<b.r;
    }
    
    inline int read(){
    	register int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return (f==1)?x:-x;
    }
    
    int fast_pow(int a,int b){
    	int ret=1;
    	for(;b;b>>=1,a=(ll)a*a%p)
    		ret=(ll)ret*(b&1?a:1)%p;
    	return ret;
    }
    
    inline void add(int x){
    	if(cnt[a[x]]) now=(ll)now*farc[cnt[a[x]]]%p;
    	now=(ll)now*inv[++cnt[a[x]]]%p;
    }
    inline void del(int x){
    	now=(ll)now*farc[cnt[a[x]]--]%p;
    	if(cnt[a[x]]) now=(ll)now*inv[cnt[a[x]]]%p;
    }
    
    int main()
    {
    	farc[1]=1;
    	for(int i=2;i<=maxn-10;i++) farc[i]=(ll)farc[i-1]*i%p;
    	inv[maxn-10]=fast_pow(farc[maxn-10],p-2);
    	for(int i=maxn-11;i>=1;i--) inv[i]=(ll)inv[i+1]*(i+1)%p;
    	int T=read();
    	while(T--){
    		memset(cnt,0,sizeof(cnt));
    		n=read(),m=read();blo=sqrt(n);
    		for(int i=1;i<=n;i++) a[i]=read(); 
    		for(int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
    		sort(q+1,q+m+1,cmp);
    		int L=1,R=0;now=1;
    		for(int i=1;i<=m;i++){
    			while(R<q[i].r) add(++R);
    			while(R>q[i].r) del(R--);
    			while(L<q[i].l) del(L++);
    			while(L>q[i].l) add(--L);
    			ans[q[i].id]=(ll)farc[q[i].r-q[i].l+1]*now%p;
    		}
    		for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    	}
    	return 0;
    }
    

    2、Lucky

    类似一个不简单的询问的处理方式

    (Code Below:)

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int maxn=100000+10;
    int n,m,k,a[maxn],b[maxn<<1],c[maxn<<1],tot,blo;ll ans[maxn],now;
    
    struct Query{
    	int l,r,v,id;
    }q[maxn<<2];
    
    bool cmp(Query a,Query b){
    	if((a.l-1)/blo!=(b.l-1)/blo)
    		return (a.l-1)/blo<(b.l-1)/blo;
    	return a.r<b.r; 
    }
    
    inline int read(){
    	register int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return (f==1)?x:-x;
    }
    
    inline void addb(int x){now+=(ll)c[k-a[x]];b[a[x]]++;}
    inline void delb(int x){now-=(ll)c[k-a[x]];b[a[x]]--;}
    inline void addc(int x){now+=(ll)b[k-a[x]];c[a[x]]++;}
    inline void delc(int x){now-=(ll)b[k-a[x]];c[a[x]]--;}
    
    inline void add(int l,int r,int v,int id){
    	q[++tot].l=l;q[tot].r=r;q[tot].v=v;q[tot].id=id;
    }
    
    int main()
    {
    	while(cin>>n>>k){
    		memset(b,0,sizeof(b));
    		memset(c,0,sizeof(c));
    		memset(ans,0,sizeof(ans));
    		tot=now=0;blo=sqrt(n);
    		for(int i=1;i<=n;i++) a[i]=read();
    		m=read();
    		int l1,r1,l2,r2;
    		for(int i=1;i<=m;i++){
    			l1=read(),r1=read(),l2=read(),r2=read();
    			add(r1,r2,1,i);
    			if(l1>1) add(l1-1,r2,-1,i);
    			if(l2>1) add(r1,l2-1,-1,i);
    			if(l1>1&&l2>1) add(l1-1,l2-1,1,i);
    		}
    		sort(q+1,q+tot+1,cmp);
    		int L=0,R=0;
    		for(int i=1;i<=tot;i++){
    			while(L<q[i].l) addb(++L);
    			while(L>q[i].l) delb(L--);
    			while(R<q[i].r) addc(++R);
    			while(R>q[i].r) delc(R--);
    			ans[q[i].id]+=(ll)q[i].v*now;
    		}
    		for(int i=1;i<=m;i++) printf("%lld
    ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    es6笔记6^_^generator
    es6笔记5^_^set、map、iterator
    es6笔记4^_^function
    es6笔记3^_^object
    关于eslint的使用与配置,以及prettier的使用
    关于查看本机ssh公钥以及生成公钥
    Github上传图片图床
    力扣剑指Offer:39. 数组中出现次数超过一半的数字
    计蒜客:求平均年龄Python方法
    力扣:面试题59. 滑动窗口的最大值Python题解
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/10003457.html
Copyright © 2020-2023  润新知