zoukankan      html  css  js  c++  java
  • 【BZOJ3809】Gty的二逼妹子序列 莫队 分块

    题目描述

      给你一个长度为(n)的数列,还有(m)个询问,对于每个询问((l,r,a,b)),输出区间([l,r])有多少范围在([a,b])的权值。

      (nleq 100000,mleq 1000000)

    题外话

      Q:这道题和BZOJ3809有什么区别呢?

      A:卡空间。

    题解

      考虑莫队。

      每次转移时如果用树状数组很明显会TLE。所以要分块。

      每(sqrt n)个数分一块。这样转移是(O(1))的,查询是(O(sqrt n))的。

      时间复杂度:(O(nsqrt m+msqrt n))

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> pll;
    void sort(int &a,int &b)
    {
    	if(a>b)
    		swap(a,b);
    }
    void open(const char *s)
    {
    #ifdef DEBUG
    	char str[100];
    	sprintf(str,"%s.in",s);
    	freopen(str,"r",stdin);
    	sprintf(str,"%s.out",s);
    	freopen(str,"w",stdout);
    #endif
    }
    int sz1,sz2;
    //sz1=sqrt(n)
    //sz2=n/sqrt(m)
    int b1(int x)
    {
    	return (x+sz1-1)/sz1;
    }
    int b2(int x)
    {
    	return (x+sz2-1)/sz2;
    }
    namespace orzzjt
    {
    	int a[100010];
    	int b[100010];
    	void change(int x,int v)
    	{
    		a[x]+=v;
    		b[b1(x)]+=v;
    	}
    	int query(int x,int y)
    	{
    		int s=0;
    		int i;
    		int bx=b1(x);
    		int by=b1(y);
    		if(bx==by)
    		{
    			for(i=x;i<=y;i++)
    				s+=a[i];
    		}
    		else
    		{
    			for(i=x;i<=bx*sz1;i++)
    				s+=a[i];
    			for(i=(by-1)*sz1+1;i<=y;i++)
    				s+=a[i];
    			for(i=bx+1;i<=by-1;i++)
    				s+=b[i];
    		}
    		return s;
    	}
    }
    struct ques
    {
    	int l,r,a,b,id;
    };
    ques b[1000010];
    int cmp(ques a,ques b)
    {
    	if(b2(a.l)!=b2(b.l))
    		return b2(a.l)<b2(b.l);
    	return a.r<b.r;
    }
    int a[100010];
    int ans[1000010];
    int c[100010];
    void add(int x)
    {
    	c[x]++;
    	if(c[x]==1)
    		orzzjt::change(x,1);
    }
    void del(int x)
    {
    	c[x]--;
    	if(!c[x])
    		orzzjt::change(x,-1);
    }
    int main()
    {
    	int n,m;
    	scanf("%d%d",&n,&m);
    	sz1=sqrt(n);
    	sz2=n/sqrt(m);
    	sz2=max(sz2,1);
    	int i;
    	for(i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for(i=1;i<=m;i++)
    	{
    		scanf("%d%d%d%d",&b[i].l,&b[i].r,&b[i].a,&b[i].b);
    		b[i].id=i;
    	}
    	sort(b+1,b+m+1,cmp);
    	int l=1,r=0;
    	for(i=1;i<=m;i++)
    	{
    		while(r<b[i].r)
    			add(a[++r]);
    		while(l>b[i].l)
    			add(a[--l]);
    		while(r>b[i].r)
    			del(a[r--]);
    		while(l<b[i].l)
    			del(a[l++]);
    		ans[b[i].id]=orzzjt::query(b[i].a,b[i].b);
    	}
    	for(i=1;i<=m;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    字符串与字典常用命令
    Python学习之路:字符串常用操作
    Python学习之路:购物车实例
    面试题2017
    c#语法学习
    结构化设计模式-桥接模式
    结构型设计模式-适配器模式
    .Net Cache
    设计模式的六大原则
    uml类图关系
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8513258.html
Copyright © 2011-2022 走看看