首页 > 其他分享 >双指针维护可交换结合贡献区间价值的正攻法

双指针维护可交换结合贡献区间价值的正攻法

时间:2024-10-12 13:13:05浏览次数:1  
标签:opt cnt gcd 攻法 int void 交换 维护 指针

对于一类区间价值 V(l,r) = a[l] opt a[l+1] opt ... opt a[r]

当我们维护双指针同时需要维护内部区间的价值时,如果操作可交换结合并且可消去(存在y,x opt y = 0),l右移时直接去掉a[l]的价值即可;如果不可消去但可重复贡献(x opt x = x),可以使用ST表计算区间贡献;如果只满足结合律 ,我们可以利用线段树额外花费log的时间计算区间贡献。这里给出一个巧妙的做法,只要这个操作可交换结合,那么不需要任何额外数据结构,每次移动指针所需维护开销均摊后即为操作复杂度的做法。

多维护一个x,把当前维护的双指针分成两部分[l,x]和[x+1,r]分别维护价值,[l,x]的部分存储一个 \(w[i](l<=i<=x)\),表示[i,x]的价值,

再维护一个数e,表示[x+1,r]的价值。当l右移超过x之后,把x设置为当前的r,重新计算[l,x]的w,e清空。每次查询只需要计算w[l] opt t的值。因为每个w只被算了一次,所以均摊复杂度是O(nk),其中k是操作复杂度。

下面给出CF2006C的代码,当中使用了这个技巧,避免了ST表维护gcd。

const int N=4e5+3;
int a[N];
struct twop{
	int w[N],l,x,r,e;
	void init(){
		l=r=x=1;
		e=0;
	}
	void addr(){
		e=gcd(e,a[r++]);
	}
	void addl(){
		++l;
		if(l<=x)return;
		x=r-1;
		w[r]=e=0;
		for(int i=x;i>=l;i--)w[i]=gcd(a[i],w[i+1]);
	}
	int get(){
		return gcd(w[l],e);
	}
}T;

void solve(){
	int n;
	cin>>n;
	ll ans=0;
	int cnt=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		if(a[i]!=a[i-1])cnt=1;
		else ++cnt;
		ans+=cnt;
		a[i-1]-=a[i];
	}
	T.init();
	for(int i=2;i<=n;i++){
		T.addr();
		int tmp;
		while(tmp=T.get(),tmp!=0&&(tmp&tmp-1)==0)
			T.addl();
		ans+=T.l-1;
	}
	cout<<ans<<endl;
}

标签:opt,cnt,gcd,攻法,int,void,交换,维护,指针
From: https://www.cnblogs.com/nkxjlym/p/18460316

相关文章

  • C++指针的基本使用
    目录一、定义和使用二、指针占用的空间三、空指针和野指针1、空指针2、野指针四、const修饰指针五、指针和数组六、指针和函数七、结构体指针一、定义和使用指针变量定义语法:数据类型*变量名;intmain(){ //1、指针的定义 inta=10;//定义整型变量a ......
  • 【C语言】语义陷阱(5):揭秘空指针与空字符串的微妙差异
    目录一、空指针(NullPointer)1.1.定义与表示1.2.用途1.3.安全性 1.4.注意事项1.5.空指针与野指针的区别1.5.1.特性对比1.5.2.安全性与风险1.5.3.编程实践二、指向空字符串的指针2.1.定义2.2.字符数组与空字符串2.3.指针的初始化2.4.空字符串的用途2......
  • go自动初始化结构体成员指针
    typeStustruct{Id*intId1*int32Id2*int64B*bool}func(this*TestBeanSuite)Test010_IniStru(){varstu=&Stu{}baseutils.InitStruNilPtrField(stu)golog.Info(stu)}2024-10-1116:49:16.190[INFO]{"Id&quo......
  • H3C交换机SSH使用RSA公钥免密登录配置
    1.使用puttygen.exe计算RSA 2.保存公钥和私钥公钥:pub.key  注意:公钥上传到交换机(FTP等方式)。私钥:private.ppk3.配置交换机<Switch>system-view[Switch]public-keylocalcreatersaTherangeofpublickeysizeis(512~2048).Ifthekeymodulusisgreatert......
  • 无缝数据流动:跨域数据交换的高效策略!
    大型企业为了业务拓展需要,会在全国乃至全球各地设立分公司和办事机构,以便更好地处理当地事务,并进行市场的开拓和客户维护,因此大型企业都会面临跨域数据交换的场景。跨域数据交换时,需要考虑多方面的问题,以确保传输的安全性、效率、合规性和成本效益:1、安全传输数据加密:在传输过......
  • const与一级指针
    const与一级指针在C/C++中,const关键字用于表示一个变量的值是不可改变的。通常,它修饰离它最近的类型,意思是它所修饰的部分不能被修改。根据它在声明中的位置,const可以修饰指针或者指针所指向的值。1.const修饰变量如果const修饰变量,则该变量是常量,不能被修改。con......
  • 华为交换机配置-VLAN配置
    1.基于端口划分VLAN(静态VLAN)1.网络拓扑图及需求2.配置命令交换机1和交换机2的配置同理,下面展示交换机1的配置<Huawei>syEntersystemview,returnuserviewwithCtrl+Z.[Huawei]sysnameSW1[SW1]vlanbatch10011003Info:Thisoperationma......
  • 认识双指针
    基本概念双指针:通常是指在数组或链表中使用两个指针(索引)来遍历或操作数据结构。方向:指针可以同向移动(如快慢指针),也可以相向移动(如对撞指针)。应用场景:适用于需要遍历整个数据结构并进行某种操作的情况,如查找、排序、反转等。常见类型2.1快慢指针定义:两个指针从同一端开始移......
  • C#项目传递图像指针到C++项目,并转换成cv::Mat图像
    一、C#传递指针地址到C++项目1、C++代码。新建C++/CLR.NetFramewrok4.8项目 .h文件#pragmaonce#include<opencv2/opencv.hpp>extern"C"__declspec(dllexport)intCropImage(cv::Mat&image,inth,intw);.cpp文件intCropImage(cv::Mat&image,inth,in......
  • 浅拷贝和深拷贝的概念与值拷贝和指针拷贝(引用拷贝)有关 浅拷贝 “指针拷贝 深拷
    在Python中,浅拷贝和深拷贝的概念与值拷贝和指针拷贝(引用拷贝)有关,但它们并不完全相同。下面是它们之间的关系和区别:浅拷贝(ShallowCopy):类似于“指针拷贝”或“引用拷贝”。浅拷贝创建了一个新的对象,但是它所含的容器对象(例如列表、字典、类的实例等)仍然指向原始对象中的容器......