Codeforces Round 960 (Div. 2)-补题

A. Submission Bait

当某个数字出现次数为奇数时,Alice就可通过选取该数取得胜利

void solve(){
	cin>>n;
	map<int,int> mp;
	for(int i=0;i<n;i++) cin>>a[i],mp[a[i]]++;
	for(int i=0;i<n;i++){
		if(mp[a[i]]%2){
			cout<<"YES"<<endl;return;
		}
	}cout<<"NO"<<endl;
}

B. Array Craft

构造题,前缀和最大即在x位置后不能出现连续的一段1,且x+1位置必须为-1,后缀和最大即y位置前不能出现连续的一段1,且y-1位置为-1,x+1位置后和y-1位置前交替1和-1,绝对值和均为0或1,x和y间均为1,这样构造就可在x处取最大前缀和,而且索引是最小的,y处取最大后缀和,而且索引是最大的

void solve(){
	cin>>n>>x>>y;
    for(int i=1;i<y;i++){
    	if((y-1)%2){
    		if(i%2) cout<<-1<<" ";
			else cout<<1<<" "; 
		}
		else{
			if(i%2) cout<<1<<" ";
			else cout<<-1<<" ";
		}
	}
	for(int i=y;i<=x;i++) cout<<1<<" ";
	for(int i=x+1;i<=n;i++){
		if((x+1)%2){
			if(i%2) cout<<-1<<" ";
			else cout<<1<<" ";
		}
		else{
			if(i%2) cout<<1<<" ";
			else cout<<-1<<" ";
		}
	}cout<<endl;
}

C. Mad MAD Sum

看了大佬发现的性质,第一轮整理后,数列会变成单调不减的数列,第二轮整理后,除了最大数可能为1,数列中剩下的元素的数量必然大于2,从第三轮开始,就是每次数列右移一位,所以就可以根据 ai*(n-i) 来算对答案的贡献了,

void solve(){
	cin>>n;
	ll sum=0,maxs=0;
	map<int,int> mp; 
    for(int i=0;i<n;i++) cin>>a[i],sum+=a[i];
    for(int i=0;i<n;i++){
    	mp[a[i]]++;
    	if(mp[a[i]]>=2&&maxs<a[i]) maxs=a[i];
    	a[i]=maxs;
    	sum+=a[i];
	}mp.clear();maxs=0;
	//for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;
	for(int i=0;i<n;i++){
    	mp[a[i]]++;
    	if(mp[a[i]]>=2&&maxs<a[i]) maxs=a[i];
    	a[i]=maxs;
	}mp.clear();
	//for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;
	for(int i=0;i<n;i++){
		sum+=a[i]*(n-i);
		//cout<<i<<" "<<a[i]<<" "<<sum<<endl;
	}cout<<sum<<endl;
}

D. Grid Puzzle

又是看大佬的,用tag1数组表示第一二个块,tag2数组表示第三四块,小于等于2的行均用操作,这样是最优的,因为可以涉及到下一行的两个,小于等于4的行,如果有块被上一行的操作消除,就考虑消剩下的块,如果大于4的行,直接用操作

void solve(){
	int ans=0;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],tag1[i]=tag2[i]=0;
	for(int i=1;i<=n;i++){
		if(!a[i]) continue;
		if(tag1[i]&&a[i]<=2) continue;
		if(tag1[i]&&tag2[i]&&a[i]<=4) continue;
		
		if(a[i]<=2) tag1[i]=tag1[i+1]=1;
		else if(a[i]<=4){
			if(tag1[i]) tag2[i]=tag2[i+1]=1;
			else if(tag2[i]) tag1[i]=tag1[i+1]=1;
		} 
		ans++;
	}cout<<ans<<endl;
}

这段代码是在之前的攻击基础上进行了进一步的构造,以实现对对象的`addrof`和`fakeobj`操作。 首先,代码通过一个循环,将猜测到的字体对象的family属性分别设置为"hammer0"到"hammer12"。这是为了构建一系列特定的字体对象。 然后,定义了两个函数:`boot_addrof`和`boot_fakeobj`。 `boot_addrof`函数接受一个参数`obj`,将该参数赋值给`arrays[257][32]`,然后将`arrays[258][0]`的值赋给`union_f[0]`。最后,通过计算得到的两个32位整数值,构建出一个64位的地址返回。 `boot_fakeobj`函数接受一个参数`addr`,将该参数赋值给`union_i[0]`和`union_i[1]`。然后,将`union_f[0]`的值赋给`arrays[258][0]`,最后返回`arrays[257][32]`的值。 接下来,代码进行了一系列的操作,用于构造特定的数据结构。 首先,创建了一个名为`arw_master`的长度为8的Uint32Array数组,以及一个名为`arw_slave`的长度为1的Uint8Array数组。然后,创建了一个名为`obj_master`的长度为8的Uint32Array数组,以及一个名为`obj_slave`的对象,其中包含一个名为`obj`的属性,其值为null。 接着,通过调用`boot_addrof`函数,将`arw_slave`和`obj_slave`对象的地址分别赋值给`addrof_slave`和`addrof_obj_slave`变量。 然后,通过设置`union_i`数组的一些特定值,构建了一个结构体对象,并将其赋值给变量`obj`。这个结构体对象包含了一个名为`jscell`的属性,其值为`union_f[0]`,一个名为`butterfly`的属性,其值为true,一个名为`buffer`的属性,其值为`arw_master`数组,以及一个名为`size`的属性,其值为0x5678。 这段代码的目的是构建一些特定的数据结构和对象,并设置了一些特定的属性值,以实现对浏览器的进一步攻击。具体的攻击方式可能包括修改对象的内部结构、实现任意读写等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值