首页 > 其他分享 >cf1322BPresent(基数排序+双指针+拆位)

cf1322BPresent(基数排序+双指针+拆位)

时间:2023-11-06 12:46:32浏览次数:32  
标签:cnt now bit int 基数排序 cf1322BPresent include 拆位 fo

cf1322BPresent
首先拆位是显然的,对于两个数a[i],a[j],除了考虑当前位上的数,我们还要考虑是否会产生进位,我们可以利用基数排序+双指针,因为我们每次都是将低位的排好序了,所以我们可以用双指针计算进位,然后分类计算一下,当前为为1的情况即可。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<unordered_map>
#include<queue>
#define A puts("YES")
#define B puts("NO")
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
#define lc (o<<1)
#define rc (o<<1|1)
#define bit ((a[i]>>id)&1)
using namespace std;
//typedef __int128 i128;
typedef double db;
typedef long long ll;
const ll mo=1e9+7;
const int N=4e5+5;
int b[31],n,a[N],c[N],cnt[2],now,ans;
int t[N][2];
int s1,s2;
bool pd(int x,int y,int d){
	s1=x&(b[d]-1);
	s2=y&(b[d]-1);
	return s1+s2>=b[d];
}
int main()
{
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);

	b[0]=1;
	fo(i,1,30) b[i]=b[i-1]*2;
	
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	
	fo(id,0,30) {
		now=0;
		
		memset(cnt,0,sizeof(cnt));
		memset(t,0,sizeof(t));
		
		fo(i,1,n) cnt[bit]++; 
		
		if (!id) {
			now+=(cnt[0]&1)*(cnt[1]&1);
		}
		else{
			
			fd(i,n,1) {
				fo(j,0,1) t[i][j]=t[i+1][j];
				t[i][bit]++;
			}
			
			int r=n;
			fo(i,1,n-1) {
				
				r=max(i+1,r);
				while (r>i+1 && pd(a[r-1],a[i],id)) r--;
				if (pd(a[r],a[i],id)) {
					now+=t[r][bit];
					now+=t[i+1][bit^1]-t[r][bit^1];
				}
				else {
					now+=t[i+1][bit^1];
				}
				now&=1;
			}
			
		}
		
		cnt[1]+=cnt[0];
		fd(i,n,1) c[cnt[bit]--]=a[i];
		fo(i,1,n) a[i]=c[i];
		if (now&1) ans+=b[id];
	}
	
	printf("%d",ans);
	
	return 0;
}

 
 

标签:cnt,now,bit,int,基数排序,cf1322BPresent,include,拆位,fo
From: https://www.cnblogs.com/ganking/p/17812381.html

相关文章

  • C#基数排序算法
    前言基数排序是一种非比较性排序算法,它通过将待排序的数据拆分成多个数字位进行排序。实现原理首先找出待排序数组中的最大值,并确定排序的位数。从最低位(个位)开始,按照个位数的大小进行桶排序,将元素放入对应的桶中。将各个桶中的元素按照存放顺序依次取出,组成新的数组。接着......
  • 深入了解基数排序:原理、性能分析与 Java 实现
    基数排序(RadixSort)是一种非比较性排序算法,它根据元素的每个位上的值来进行排序。基数排序适用于整数或字符串等数据类型的排序。本文将详细介绍基数排序的原理、性能分析及java实现。基数排序原理基数排序的基本原理是按照低位先排序,然后收集;再按照高位排序,再收集;以此类推,直到最高......
  • 拆位
    占坑H-ProblemH.xor_2021CCPC新疆省赛P9236[蓝桥杯2023省A]异或和之和SumofXORFunctionsI-TheYakumoFamily_2023牛客暑期多校训练营5(nowcoder.com)......
  • 基数排序(这里假设数据的最高位为3)
    基本思想:在需要排序的一串数据中,取最长位数为参考,不足最长位数的数据要在前面补零,然后形成一串相同位数的数据,最后通过比较这串数据的个位数,十位数,百位数….最后就会得到一个有序的序列。用Java实现如下所示:importjava.util.Arrays;publicclassTest1{publicstaticvo......
  • 堆排序 桶排序 基数排序
    堆排序使用数组和表示堆大小的整数heapSize表示堆:vector<int>arr{9,5,3,7,2};intheapSize=5;heapSize=5表示数组从索引0开始的5个元素表示一个堆。堆结构就是用数组实现的完全二叉树结构。求数组中索引i位置节点的父子节点:父节点:(i-1)/2左子节点:2*i+1右子节......
  • 基数排序
     基数排序,不是基于比较的排序。过程如下:处理过程:  桶排过程:1voidBucket_sort(inta[],intexp)//exp为1按个位排序,exp为10按十位排序,exp为100按个位排序,……2{3vector<int>Bucket[20];45//按位入桶,+10是为了对付负数6for(int......
  • 【数据结构】排序 归并排序和基数排序
    1.归并排序归并排序中的"归并"的意义就是把多个有序表合并为一个新的有序表。算法思想:二路归并排序:初始情况下将长度为n的待排序表分为n个子表,则每个子表的长度为1,是有序的。每趟排序尽量将这些子表按位置相邻两两归并,重复直到合并为一个长度为n的有序表为止。具体实现:在归......
  • 归并,基数排序及排序分析
    归并,基数排序及排序分析归并排序将两个或两个以上的有序子序列"归并"为一个有序的序列.归并排序的演示归并需要logn趟如何将两个有序序列合成一个有序序列?使用前面学的两个线性表的合并在同一个有序序列里面的合并操作归并排序算法分析归并排序方法的比较基数......
  • 基数排序
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-#O(n)O(kn)#NBO(nlogn)importrandomdefpartition(li,left,right):tmp=li[left]whileleft<right:whileleft<rightandli[right]>=tmp:#从右面找比tmp小的数......
  • 基数排序详解
    基数排序详解1)前言:计数排序要学基数排序,掌握计数排序非常重要。计数排序的原理十分的简单。举个例子,排序52413,你打算怎么办?很简单是不是,冒泡排序、选择排序、归并排序……这些都足以解决。但如果你有100000000个数要排序,你可能就要束手就擒了。那如归这时候我告诉你:这1000......