zoukankan      html  css  js  c++  java
  • [UR#22] 月球列车

    一、题目

    点此看题

    这种比较精细的题还是要多练练,其实不怎么难但是我看题解都看了三个小时

    二、解法

    位运算和四则运算混合在一起是很恶心的,方法基本上只有按位考虑。

    对于数位 (w),我们只需要考虑 (a_i/x) 在数位 (w) 出现次数的奇偶性,和考虑 (a_i+x)(w-1) 这个数位上进位次数的奇偶性即可,前者特别容易计算,难点是后者。

    一定要记住这种进位问题是有单调性的,我们把 (a_i) 按前 (w-1) 位从小到大排序后,能产生进位的一定是一段后缀,设 (V=2^w-xand(2^w-1)),进位的充要条件是 (a_iand(2^w-1)geq V)

    如果暴力预处理排序、查询时候暴力二分的话时间复杂度 (O(nlog nlog a))

    考虑优化,因为二进制的特性我们可以在排序的时候使用归并排序。查询时候我们想快速得到 (V) 在数组上的位置,可以预处理 (c[w][i][0/1]) 表示以前第 (i) 个位置上的数,考虑第 (w) 位之后,不加 (2^w/)加上 (2^w) 在新数组中的位置。

    假设我们知道 (V) 以前在数组中的位置,可以通过跳 (c) 数组来处理出 (V) 在数组中的新位置,这样求出来的是小于等于 (V) 的最后一个位置。对于计算答案,如果 (x) 这一位为 (0) 那么我们找在 ([V,V+2^w)) 中的数个数,因为 (a_igeq V+2^w) 会因为进位和原本这一位就有值贡献被抵消了;如果 (x) 这一位为 (1) 那么贡献的数全部取反即可。

    时间复杂度 (O(nlog a))真的是道签到题呢

    #include <cstdio>
    #include <cstring>
    const int M = 250005;
    #define int long long
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,t,a[M],c[64][M][2],tmp[M],cur[M];
    int work(int x)
    {
    	int cur=n,ans=0;
    	for(int w=0;w<=60;w++)
    	{
    		int cnt=c[w][cur][1]-c[w][cur][0];
    		if(!((x>>w)&1)) cur=c[w][cur][1];
    		else cnt=n-cnt,cur=c[w][cur][0];
    		if(cnt&1) ans|=(1ll<<w);
    	}
    	return ans;
    }
    signed main()
    {
    	n=read();m=read();t=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read(),cur[i]=i;
    	for(int w=0;w<=60;w++)
    	{
    		int cnt=0;
    		c[w][0][0]=cnt;
    		for(int i=1;i<=n;i++)
    		{
    			if(!((a[cur[i]]>>w)&1)) tmp[++cnt]=cur[i];
    			c[w][i][0]=cnt;
    		}
    		c[w][0][1]=cnt;
    		for(int i=1;i<=n;i++)
    		{
    			if((a[cur[i]]>>w)&1) tmp[++cnt]=cur[i];
    			c[w][i][1]=cnt;
    		}
    		memcpy(cur,tmp,sizeof cur);
    	}
    	int ans=0;
    	for(int i=1;i<=m;i++)
    	{
    		int x=read();
    		if(t) x^=(ans>>20);
    		ans=work(x);
    		printf("%lld
    ",ans);
    	}
    } 
    
  • 相关阅读:
    sshd服务(使用ssh协议远程开启其他主机shell的服务)
    centos 端口及防火墙
    Linux系统常用指令积累
    Vue插值
    Vue生命周期钩子
    WinForm常用窗体属性及控件
    SQL Server 如何设置某列自增
    .mdf和.ldf文件导入SQL server 数据库
    .netCoreApi 定时任务
    c# web请求
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/15375981.html
Copyright © 2011-2022 走看看