• #链表#洛谷 3794 签到题IV


    题目

    给出一个长度为(n)的数列(a),求

    [sum_{i=1}^nsum_{j=i}^n[gcd(a_{isim j});xor;or(a_{isim j})=k] ]


    分析

    考虑如何优化这个(O(n^2logn))的方法,显然无论是(gcd)还是(or)都有连续位置答案是一定的
    考虑每次在后面加入一个数后,从1开始更新(gcd)(or),如果遇到(gcd)或者(or)相同的一段,用链表将其合并
    如果(gcd)下一个位置在(or)下一个位置之前那么跳到下一个(gcd),否则跳到下一个(or),我不会证明,但是时间复杂度应该是(O(nlogn))


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=500011; long long ans;
    int Gcd[N],Or[N],a[N],n,k,Guf[N],Gre[N],Ouf[N],Ore[N];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed min(int a,int b){return a<b?a:b;}
    inline signed gcd(int a,int b){return !b?a:gcd(b,a%b);}
    inline void doit(int ed){
    	for (rr int st=1;st<=ed;){
    		Gcd[st]=gcd(Gcd[st],a[ed]),Or[st]|=a[ed];
    		if (Gcd[st]==(Or[st]^k)) ans+=min(Guf[st],Ouf[st])-st;//这一段都是答案
    		if (Gcd[st]==Gcd[Gre[st]]) Guf[Gre[st]]=Guf[st],Gre[Guf[st]]=Gre[st];//gcd相等合并
    		if (Or[st]==Or[Ore[st]])   Ouf[Ore[st]]=Ouf[st],Ore[Ouf[st]]=Ore[st];//or相等合并
    		if (Guf[st]<Ouf[st]) Or[Guf[st]]=Or[st],Ouf[Guf[st]]=Ouf[st],Ore[Guf[st]]=Ore[st];//先把原先合并的段拆成两部分
    		if (Guf[st]>Ouf[st]) Gcd[Ouf[st]]=Gcd[st],Guf[Ouf[st]]=Guf[st],Gre[Ouf[st]]=Gre[st];//同上
    		st=min(Guf[st],Ouf[st]);//跳到下一个
    	}
    }
    signed main(){
    	n=iut(),k=iut();
    	for (rr int i=1;i<=n;++i) Gcd[i]=Or[i]=a[i]=iut();
    	for (rr int i=1;i<=n;++i) Gre[i]=Ore[i]=i-1,Guf[i]=Ouf[i]=i+1;//链表
    	for (rr int i=1;i<=n;++i) doit(i);
    	return !printf("%lld",ans);
    }
    
  • 相关阅读:
    0705-深度网络模型持久化
    0704-使用GPU加速_cuda
    0703-可视化工具tensorboard和visdom
    0702-计算机视觉工具包torchvision
    00-凸优化引言
    MySQL数据库从入门到放弃(目录)
    0701-数据处理
    BurpSuite抓取HTTPS请求&&拦截Android请求
    数学里的e到底指什么
    QGeoPolygon
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13527140.html
Copyright © 2020-2023  润新知