Codeforces Round 969 (Div. 1) C. Eri and Expanded Sets(线段树维护差分数组gcd+双指针+尺取)

题目

转化一下题意就是,

给定一个n(n<=4e5),代表数组a的长度,

求有多少区间,满足区间内两两差分后得到的新数组的gcd∈{0,1}

实际t(t<=1e4)组样例,保证sumn不超过4e5

思路来源

乱搞ac+jiangly代码

题解

一个重要的性质是,

区间内从小到大排好序相邻两项两两差分的gcd,等于区间内不排序相邻两项两两差分的gcd

以下的代码1是用了这个性质的,所以直接维护相邻项gcd即可,比较好写

代码2是在权值线段树上强行排了一下序的,非常难写

双指针维护一下,

对于枚举的右端点r,满足区间[l,r]的相邻项差分数组的gcd=1的最靠右的l,

由于gcd只会缩成因子,所以对于所有<=l的位置x,[x,r]的gcd都是等于1的,直接ans+=l

具体代码里是,在[l,r]区间长度不短于2的前提下,试着把当前l往右挪一个,

只要gcd为1的话就可以一直往右挪,否则break,并往左回滚一个

特别地,gcd=0和gcd=1不能放在一起维护,否则不满足双指针的单调性了,所以这里分开统计的

gcd=0的段就是区间内所有值都相同的段,尺取即可

代码1

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
const int N=4e5+10;
int t,n,a[N],l,r,kd;
int gcd(int x,int y){return !y?x:gcd(y,x%y);
}
struct segtree{int n;struct node{int l,r,v;}e[N<<2];#define l(p) e[p].l#define r(p) e[p].r#define v(p) e[p].vvoid up(int p){v(p)=gcd(v(p<<1),v(p<<1|1));}void bld(int p,int l,int r){l(p)=l;r(p)=r;v(p)=0;if(l==r){return;}int mid=l+r>>1;bld(p<<1,l,mid);bld(p<<1|1,mid+1,r);up(p);}void init(int _n){n=_n;bld(1,1,n);}void chg(int p,int x,int v){if(l(p)==r(p)){v(p)=v;return;}int mid=l(p)+r(p)>>1;chg(p<<1|(x>mid),x,v);up(p);}bool ok(){int x=v(1);if(!x)return 0;x-=x&(-x);return !x;}
}seg;
int main(){sci(t);while(t--){sci(n);rep(i,1,n){sci(a[i]);}seg.init(n);int l=1;ll ans=0;rep(r,2,n){//gcd=1的区间 满足x<=l的所有[x,r]seg.chg(1,r,abs(a[r]-a[r-1]));if(!seg.ok())continue;while(l+1<r && seg.ok()){seg.chg(1,l+1,0);l++;//printf("l:%d r:%d query:%d\n",l,r,seg.query());}//printf("l:%d r:%d query:%d\n",l,r,seg.query());if(!seg.ok()){seg.chg(1,l,abs(a[l]-a[l-1]));l--;}//printf("l:%d r:%d ok:%1d\n",l,r,seg.ok());ans+=l;}int p=0;rep(r,1,n){//gcd=0的区间 满足所有值都相同的区间if(r==1 || a[r]==a[r-1])p++;else ans+=1ll*p*(p+1)/2,p=1;}ans+=1ll*p*(p+1)/2;printf("%lld\n",ans);}return 0;
}

代码2(乱搞ac)

相当于给动态维护的区间[l,r]拍到一棵权值线段树上了,

并且需要维护每种数字出现的个数,和当前出现的数字的种类数,比较繁琐

#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
const int N=4e5+10;
int t,n,a[N],b[N],x[N],q[N],c,l,r,kd;
int gcd(int x,int y){return !y?x:gcd(y,x%y);
}
int LG(int n){return std::__lg(n);// int highestBit = 0;// while (n >>= 1) {//     highestBit++;// }// return highestBit;
}
struct segtree{int n;struct node{int l,r,v;}e[N<<2];#define l(p) e[p].l#define r(p) e[p].r#define v(p) e[p].vvoid up(int p){v(p)=gcd(v(p<<1),v(p<<1|1));//if(p==1)rep(i,1,17)printf("p:%d v:%d\n",i,v(i));//while(v(p) && v(p)%2==0)v(p)/=2;}void bld(int p,int l,int r){l(p)=l;r(p)=r;//printf("p:%d l:%d r:%d\n",p,l,r);if(l==r){v(p)=0;return;}int mid=l+r>>1;bld(p<<1,l,mid);bld(p<<1|1,mid+1,r);up(p);}void init(int _n){n=_n;bld(1,1,n);}void chg(int p,int x,int v){if(l(p)==r(p)){//if(v==410)printf("vvv");//while(v && v%2==0)v/=2;v(p)=v;return;}int mid=l(p)+r(p)>>1;chg(p<<1|(x>mid),x,v);up(p);}int cnt(int p,int ql,int qr){if(ql<=l(p)&&r(p)<=qr)return v(p);int mid=l(p)+r(p)>>1,res=0;if(ql<=mid)res|=cnt(p<<1,ql,qr);if(qr>mid)res|=cnt(p<<1|1,ql,qr);return res;}bool ok(){int x=v(1);x-=x&(-x);return !x;}int query(){return v(1);}
}seg;
struct BitPre{ // 求前缀和(可改为max等)int n,tr[N];void init(int _n){n=_n;memset(tr,0,(n+1)*sizeof(*tr));}void add(int x,int v){for(int i=x;i<=n;i+=i&-i)tr[i]+=v;}int sum(int x){int ans=0; for(int i=x;i;i-=i&-i)ans+=tr[i];return ans;}int askp(int p){return sum(p)-sum(p-1);}// 树状数组求从小到大第k个, 1<=k<=sum(n), 1<=x<=nint kth(int k){int x=0;for(int i=1<<LG(n);i;i>>=1){if(x+i<=n && k>tr[x+i]){x+=i;k-=tr[x];}}return x+1;}
}tr;
void add(int r){if(!q[b[r]])kd++;q[b[r]]++;//printf("r:%d kd:%d\n",r,kd);//q.insert(r);tr.add(b[r],1);int pre=tr.sum(b[r]-1);if(pre){int w=tr.kth(pre);//if(r==5)printf("r:%d w:%d delta:%d\n",r,w,x[b[r]-1]-x[w-1]);seg.chg(1,b[r],x[b[r]-1]-x[w-1]);}int now=tr.sum(b[r]),all=tr.sum(c);//printf("r:%d now:%d all:%d\n",r,now,all);if(now<all){int w=tr.kth(now+1);//if(r==5)printf("r:%d w:%d delta:%d\n",r,w,x[w-1]-x[b[r]-1]);seg.chg(1,w,x[w-1]-x[b[r]-1]);}
}
void del(int r){q[b[r]]--;if(!q[b[r]])kd--;tr.add(b[r],-1);if(tr.askp(b[r]))return;seg.chg(1,b[r],0);int now=tr.sum(b[r]),all=tr.sum(c);//printf("del r:%d now:%d all:%d\n",r,now,all);if(now<all){int w=tr.kth(now+1);//printf("xw:%d br:%d\n",x[w-1],x[b[r]-1]);if(now){int pre=tr.kth(now);//printf("del l:%d now:%d all:%d w:%d\n",r,now,all,w,pre);seg.chg(1,w,x[w-1]-x[pre-1]);}else{//printf("del l:%d w:%d zero xw:%d\n",r,w,x[w-1]);seg.chg(1,w,0);}}
}
int main(){sci(t);while(t--){sci(n);c=0;kd=0;rep(i,1,n){sci(a[i]);q[i]=0;x[c++]=a[i];}sort(x,x+c);c=unique(x,x+c)-x;rep(i,1,n){b[i]=lower_bound(x,x+c,a[i])-x+1;}//rep(i,0,c-1)printf("i:%d x:%d\n",i+1,x[i]);tr.init(c);seg.init(c);int l=1;ll ans=0;// rep(r,1,n){//     vector<int>now;//     now.pb(x[b[r]-1]);//     per(l,r-1,1){//         now.pb(x[b[l]-1]);//         sort(now.begin(),now.end());//         int g=0,las=now[0];//         for(auto &v:now){//             g=gcd(g,v-las);//             las=v;//         }//         if(g==0 || g==1){//             printf("l:%d r:%d g:%d\n",l,r,g);//             break;//         }//     }// }rep(r,1,n){add(r);//printf("l:%d r:%d query:%d\n",l,r,seg.query());///if(!seg.ok())continue;if(kd==1)continue;//printf("r:%d kd:%d\n",r,kd);if(!seg.ok())continue;while(kd>1 && seg.ok()){del(l);l++;//printf("l:%d r:%d query:%d\n",l,r,seg.query());}//printf("l:%d r:%d query:%d\n",l,r,seg.query());if(kd==1 || !seg.ok())add(--l);//printf("l:%d r:%d query:%d\n",l,r,seg.query());ans+=l;}int p=0;rep(r,1,n){if(r==1 || a[r]==a[r-1])p++;else ans+=1ll*p*(p+1)/2,p=1;}ans+=1ll*p*(p+1)/2;printf("%lld\n",ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148322.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

摆脱困境并在 Android 手机上取回删除照片的所有解决方案

没有什么比不小心从 Android 智能手机中删除所有照片更糟糕的了。这样&#xff0c;除非您在重置之前已经备份了数据&#xff0c;否则您的所有照片都会消失。如果您忘记备份照片&#xff0c;您仍然可以按照一些简单的技术在 Android 设备上恢复已删除的照片。 您的 Android 智能…

【漏洞复现】用友 NC-Cloud queryStaffByName Sql注入漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

VMware安装ubuntu24.04桌面版

一、安装推荐要求 双核2 GHz处理器或更高 4 GB系统内存 25 GB磁盘存储空间 可访问的互联网 光驱或USB安装介质 二、下载桌面系统 下载地址&#xff08;使用手机转存再下载是对作者的最大支持&#xff09;&#xff1a;夸克网盘分享 (quark.cn) 已安装的纯净版ubuntu虚拟…

招联金融2025秋招--大量招后台、算法

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策划 产品运营…

Day05 日期类OJ题目

计算日期到天数转换_牛客题霸_牛客网根据输入的日期&#xff0c;计算是这一年的第几天。 保证年份为4位数且日期合法。 进阶&#xff1a;时。题目来自【牛客题霸】https://www.nowcoder.com/share/jump/4938575031726974727572 根据输入的日期&#xff0c;计算是这一年的第几…

Golang | Leetcode Golang题解之第429题N叉树的层序遍历

题目&#xff1a; 题解&#xff1a; func levelOrder(root *Node) (ans [][]int) {if root nil {return}q : []*Node{root}for q ! nil {level : []int{}tmp : qq nilfor _, node : range tmp {level append(level, node.Val)q append(q, node.Children...)}ans append(a…

HTML和CSS做一个无脚本的手风琴页面(保姆级)

一、前言 使用HTML和CSS做一个无脚本的手风琴页面。让知识以自己喜欢的方式进入脑子&#xff0c;适用于很多场景&#xff0c;比如以下&#xff1a; 【注&#xff1a;图片源自百度】 二、HTML框架 使用外部样式表&#xff0c;将CSS文件用link标签引入 整体框架如下图&#x…

20240923 每日AI必读资讯

GPT-4o能玩《黑神话》&#xff01;精英怪胜率超人类&#xff0c;无强化学习纯大模型方案 - 阿里巴巴的研究人员们提出了一个新型VARP&#xff08;视觉动作角色扮演&#xff09;智能体框架。 - 能直接将游戏截图作为输入&#xff0c;通过视觉语言模型推理&#xff0c;最终生成…

WebGL颜色与纹理

WEBGL中的着色器变量包括以下种类&#xff1a; 属性变量&#xff08;Attribute Variables&#xff09;&#xff1a;这些变量用于接收从应用程序中传递的顶点数据&#xff0c;比如顶点位置和颜色&#xff0c;是只读的不可修改。统一变量&#xff08;Uniform Variables&#xff…

STM32篇:开发环境安装

编程语言&#xff1a;C语言 需要安装的软件有两个&#xff1a;Keil5 和 STM32CubeMX 一.Keil5 的安装 使用 Keil4 写 STM32 代码其实也是可以&#xff0c;但需要很复杂的配置&#xff0c;不建议新手操作。 比较推荐 Keil5 编写 STM32 &#xff0c;只需要一些简单的设置就可…

定了,东湖高新区下半年中高级职称申报时间

2024年东湖高新区中级职称申报开始了&#xff0c;水测成绩上周已出&#xff0c;本周已经开始申报了&#xff0c;时间确实挺着急的。 报送材料起止时间及地点&#xff1a; &#xff08;一&#xff09;网上报名时间&#xff1a; 2024年9月14日至9月30日24:00 &#xff08;二&…

C++ | Leetcode C++题解之第429题N叉树的层序遍历

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> levelOrder(Node* root) {if (!root) {return {};}vector<vector<int>> ans;queue<Node*> q;q.push(root);while (!q.empty()) {int cnt q.size();vector<…

C/C++中的内存管理

文章目录 前言一、C/C中的内存分布二、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 三、C中的内存管理方式四、operator new与operator delete函数五、new和delete的实现原理 六、定位new表达式(placement-new) 七、malloc/free和new/delete的区别 总结 前…

django学习入门系列之第十点《A 案例: 员工管理系统15》

文章目录 15 认识Ajax15.4 ajax请求的返回值实例2&#xff1a;前端输入数据提交到后端实例3&#xff1a;传输多个数据 往期回顾 15 认识Ajax 15.4 ajax请求的返回值 一般数据交互整合的都是json格式 后端一般会返回一个JSON格式 返回json格式一般有以下两种写法 上面注释的…

【全网最全】2024年华为杯研究生数学建模A题成品论文

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接获取群聊【2024华为杯研赛资料汇总】&#xff1a;https://qm.qq.com/q/yB6JDUTaWAhttps://qm.qq.com/q/yB6JDUTaWAA题第一问是关于如何建立一个低复杂度模型&a…

Java--File

FIle 概述 File的构造方法 > 1. 一个File对象代表硬盘中实际存在的一个文件或者目录。 > 2. 无论该路径下是否存在文件或者目录&#xff0c;都不影响File对象的创建。 代码演示&#xff1a; // 文件路径名 String pathname "D:\\aaa.txt"; File file1 new …

一些迷你型信息系统 - 2

1 Linux内核数据结构信息查询 Linux内核的数据结构众多&#xff0c;成千上万&#xff0c;做一个程序来存储查询信息&#xff1b;自己录入数据&#xff1b; 代码字段最长可录入65535个字符&#xff1b;每个字段录入时长度超限会有红色告警&#xff1b; 其他的以后想到再做&#…

5分钟快速制作高质量、美观的Excel甘特图

你是否还在为如何制作甘特图而感到苦恼&#xff1f; 是否因为甘特图制作过程繁琐、耗时过长而影响了你的工作效率&#xff1f; 是否每当任务计划发生变更时&#xff0c;都需要反复重新绘制甘特图&#xff0c;让你感到疲惫不堪&#xff1f; 又或者&#xff0c;你是否一直渴望…

【AI算法岗面试八股面经【超全整理】——NLP】

AI算法岗面试八股面经【超全整理】 概率论【AI算法岗面试八股面经【超全整理】——概率论】信息论【AI算法岗面试八股面经【超全整理】——信息论】机器学习【AI算法岗面试八股面经【超全整理】——机器学习】深度学习【AI算法岗面试八股面经【超全整理】——深度学习】NLP【A…

cmd快速进入文件夹目录下

首先&#xff0c;将文件夹直接点击左键拖动至cmd窗口中&#xff0c;就可以得到目录路径。 还有就是&#xff0c;在命令行直接敲入D:或者C:就可以在磁盘之间进行转换&#xff0c;注意冒号不要丢。 再有&#xff0c;如果进入某磁盘中的一个文件夹&#xff0c;使用cd命令。路径获取…