• P5072 [Ynoi2015]盼君勿忘


    题目链接

    题意分析

    插点题外话
    
    我感觉我已经不可能再获得幸福了
    因为
    我已经被幸福包围了
    
    珂朵莉,欢迎回家
    

    每一次做这种题面都会泪目的

    由于这种题只存在询问 所以我们不自觉的想到了莫队

    首先 如果区间[l,r]中的一个数x出现了k次的话 那么ta在所有子序列里面出的次数就是(2^{r-l+1}-2^{r-l+1-k})

    然后的话 我们使用莫队 维护每一个数x出现了的次数k 出现k次的数的和 区间里面所有的k

    每一个数x出现了的次数k:由于(a_i≤10^5) 所以我们直接开桶维护就可以了 离散化都不带的

    出现k次的数的和:我们也可以直接使用数组维护 但是需要注意的是为了防止重复 我们需要在每一次修改次数的时候进行特判

    区间里面所有的k:这里的话也是需要去重的 我们可以使用一个叫做unordered_set的东西加以维护 就像set一样具有insert,erase,find等操作

    跟set相比 unordered_set正如其名 不存在有序性 这里也不需要什么有序性 所以可以当作一个可去重的数组来使用

    然后的话 我们直接通过unorder_set里面的k进行答案的累加就可以了

    等一下 你觉得这样的话 就可以过了吗?

    这题是需要卡常数的看在珂朵莉的面子上我就不追究了

    卡常数技巧:

    1.莫队排序的奇偶优化

    struct Node
    {
    	int le,ri,id;
    	long long mod;
    	friend bool operator <(const Node &A,const Node &B)
    	{
    		if(bel[A.le]^bel[B.le]) return A.le<B.le;
    		else return (bel[A.le]&1) ? A.ri<B.ri : A.ri>B.ri;
    	}
    }e[N];
    

    2.求2的指数幂时的优化

    由于这里指数的最高上限是n 所以我们可以考虑一下(sqrt{n})预处理求指数幂

    就是(2^x=2^{frac{x}{sqrt{n}}×sqrt{n}+x\%sqrt{n}})

    //sq=sqrt(n);
    
    long long getpow(int x,long long p)
    {return (qpow[(x/sq)*sq]*qpow[x%sq])%p;}
    
    for(int j=1;j<=sq;++j) qpow[j]=qpow[j-1]*2LL%e[i].mod;
    for(int j=2;j*sq<=(e[i].ri-e[i].le+1);++j)
    

    3.undered_set的使用

    【安逸一个不戳的大佬博客】

    为什么我们使用unordered_set而不使用set

    由于跟set相比 unordered_set更像是一个散列表 所以insert、erase以及find的平均复杂度相比于set来讲优秀很多

    自然也就成为了一个卡常数技巧

    CODE:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<unordered_set>
    #define N 100080
    using namespace std;
    int n,q,tot,sq;
    int num[N],vis[N],bel[N];
    long long qpow[N],sum[N],ans[N];
    unordered_set<int> allsum;
    struct Node
    {
    	int le,ri,id;
    	long long mod;
    	friend bool operator <(const Node &A,const Node &B)
    	{
    		if(bel[A.le]^bel[B.le]) return A.le<B.le;
    		else return (bel[A.le]&1) ? A.ri<B.ri : A.ri>B.ri;
    	}
    }e[N];
    long long getpow(int x,long long p)
    {return (qpow[(x/sq)*sq]*qpow[x%sq])%p;}
    void add(int x)
    {
    	if(vis[num[x]])
    	{
    		sum[vis[num[x]]]-=num[x];
    		if(!sum[vis[num[x]]]) allsum.erase(vis[num[x]]);
    	}
    	vis[num[x]]++;
    	if(!sum[vis[num[x]]])
    	{
    		sum[vis[num[x]]]+=num[x];
    		allsum.insert(vis[num[x]]);
    	}
    	else sum[vis[num[x]]]+=num[x];
    }
    void del(int x)
    {
    	sum[vis[num[x]]]-=num[x];
    	if(!sum[vis[num[x]]]) allsum.erase(vis[num[x]]);
    	vis[num[x]]--;
    	if(!vis[num[x]]) return;
    	
    	if(!sum[vis[num[x]]])
    	{
    		sum[vis[num[x]]]+=num[x];
    		allsum.insert(vis[num[x]]);
    	}
    	else sum[vis[num[x]]]+=num[x];
    }
    void solve()
    {
    	int lenow=1,rinow=0;
    	for(int i=1;i<=q;++i)
    	{
    		qpow[0]=1LL;
    		for(int j=1;j<=sq;++j) qpow[j]=qpow[j-1]*2LL%e[i].mod;
    		for(int j=2;j*sq<=(e[i].ri-e[i].le+1);++j)
    		qpow[j*sq]=qpow[(j-1)*sq]*qpow[sq]%e[i].mod;
    		while(rinow<e[i].ri) add(++rinow);
    		while(lenow>e[i].le) add(--lenow);
    		while(lenow<e[i].le) del(lenow++);
    		while(rinow>e[i].ri) del(rinow--);
    		for(unordered_set<int>::iterator key=allsum.begin();key!=allsum.end();++key)
    		{
    			int now=*key;
    			ans[e[i].id]=(ans[e[i].id]+sum[now]*(getpow(rinow-lenow+1,e[i].mod)-getpow(rinow-lenow+1-now,e[i].mod)+e[i].mod)%e[i].mod)%e[i].mod;
    		}
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&q);sq=(int)sqrt(1.0*n);
    	for(int i=1;i<=n;++i) scanf("%d",&num[i]);
    	for(int i=1;i<=n;++i) bel[i]=(i/sq)+1;
    	
    	for(int i=1;i<=q;++i)
    	{
    		scanf("%d%d%lld",&e[i].le,&e[i].ri,&e[i].mod);
    		e[i].id=i;
    	}
    	sort(e+1,e+q+1);
    	solve();
    	for(int i=1;i<=n;++i)
    	printf("%lld
    ",ans[i]);
    	return 0;
    } 
    
  • 相关阅读:
    Unity 摄像机Clear Flags和Culling Mask属性用途详解
    Unity 坐标系
    Unity 模型导入导出
    Unity 序列化
    正确理解静态Static关键字
    Unity 中的协同程序
    Asp.Net中调用存储过程并返回输出参数
    php学习知识点
    Jauery 中Ajax的几种异步请求
    2014年12月21号面试
  • 原文地址:https://www.cnblogs.com/LovToLZX/p/14028122.html
Copyright © 2020-2023  润新知