Div2 936 D. Birthday Gift

解题思路

  • 题意为将一数组从头到尾划分,每组组内异或,异或后的结果再或起来满足小于等于x,问最多划分组数
  • 考虑使数组划分后该位为0的最多划分
  • 即划分后每个子段内该位只有2个1或0个1
  • x=x+1,\leq \rightarrow <
  • 满足小于条件,即y二级制下从高位开始比较,第一个x=1,y=0之前没有不同,之后任意
  • 考虑如何找
  • 从高位到低位,逐位满足约束(之前没有不同的)
  • 若当前位x=1,且划分使得y=0,则答案可能为当前划分数
  • 若当前位x=1,且不存在划分使得y=1满足约束,则退出
  • 若当前位x=0,但无法划分使得y=0,则之后均无法满足小于,退出
  • 若当前位x=0,且可以划分使得y=0,则更新划分,满足约束
import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;













//implements Runnable
public class Main {
	static long md=(long)998244353;
	static long Linf=Long.MAX_VALUE/2;
	static int inf=Integer.MAX_VALUE/2;
	static int N=2000010;
	static int n=0;
	static int m=0;


	static void solve() throws Exception{
		AReader input=new AReader();
//		Scanner input=new Scanner(System.in);
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));	
		String al="abcdefghijklmnopqrstuvwxyz";
		char[] ac=al.toCharArray();

		int T=input.nextInt();
		while(T>0) {
			T--;	
			n=input.nextInt();
			long x=input.nextLong();
			x++;
			Vector<Long> a=new Vector<Long>();
			for(int i=1;i<=n;++i)a.add(input.nextLong());
			long k=-1;
			for(int i=30;i>=0;--i) {//逐位满足约束
				Vector<Long> b=new Vector<Long>();
				
				boolean hs=false;
				long now=0;
				for(Long y:a) {//进行划分看能否使该位为0
					if(hs) now^=y;
					else now=y;
					if(((now>>i)&1)==1)hs=true;
					else {
						b.add(now);
						hs=false;
					}
				}
				if(((x>>i)&1)==1){//当前位为1,且可以划分出0,则低位任意,答案为划分个数
					if(!hs) {
						k=Math.max(k, b.size());
						if(b.size()==a.size())break;//无法划分使得该位为1满足约束,退出,其实后面得划分也不会更优
					}
				}else {
					if(hs)break;//当前位为0,但无法划分出0,不满足小于约束,之后也不会满足
					a=b;//满足约束,更新划分
				}
			}
			out.println(k);
 		}
		
	    out.flush(); 
	    out.close();
	}
	public static void main(String[] args) throws Exception{
		solve();
	}
//	public static final void main(String[] args) throws Exception {
//		  new Thread(null, new Tx2(), "线程名字", 1 << 27).start();
//	}
//		@Override
//		public void run() {
//			try {
//				//原本main函数的内容
//				solve();
//
//			} catch (Exception e) {
//			}
//		}
		static
		class AReader{ 
		    BufferedReader bf;
		    StringTokenizer st;
		    BufferedWriter bw;

		    public AReader(){
		        bf=new BufferedReader(new InputStreamReader(System.in));
		        st=new StringTokenizer("");
		        bw=new BufferedWriter(new OutputStreamWriter(System.out));
		    }
		    public String nextLine() throws IOException{
		        return bf.readLine();
		    }
		    public String next() throws IOException{
		        while(!st.hasMoreTokens()){
		            st=new StringTokenizer(bf.readLine());
		        }
		        return st.nextToken();
		    }
		    public char nextChar() throws IOException{
		        //确定下一个token只有一个字符的时候再用
		        return next().charAt(0);
		    }
		    public int nextInt() throws IOException{
		        return Integer.parseInt(next());
		    }
		    public long nextLong() throws IOException{
		        return Long.parseLong(next());
		    }
		    public double nextDouble() throws IOException{
		        return Double.parseDouble(next());
		    }
		    public float nextFloat() throws IOException{
		        return Float.parseFloat(next());
		    }
		    public byte nextByte() throws IOException{
		        return Byte.parseByte(next());
		    }
		    public short nextShort() throws IOException{
		        return Short.parseShort(next());
		    }
		    public BigInteger nextBigInteger() throws IOException{
		        return new BigInteger(next());
		    }
		    public void println() throws IOException {
		        bw.newLine();
		    }
		    public void println(int[] arr) throws IOException{
		        for (int value : arr) {
		            bw.write(value + " ");
		        }
		        println();
		    }
		    public void println(int l, int r, int[] arr) throws IOException{
		        for (int i = l; i <= r; i ++) {
		            bw.write(arr[i] + " ");
		        }
		        println();
		    }
		    public void println(int a) throws IOException{
		        bw.write(String.valueOf(a));
		        bw.newLine();
		    }
		    public void print(int a) throws IOException{
		        bw.write(String.valueOf(a));
		    }
		    public void println(String a) throws IOException{
		        bw.write(a);
		        bw.newLine();
		    }
		    public void print(String a) throws IOException{
		        bw.write(a);
		    }
		    public void println(long a) throws IOException{
		        bw.write(String.valueOf(a));
		        bw.newLine();
		    }
		    public void print(long a) throws IOException{
		        bw.write(String.valueOf(a));
		    }
		    public void println(double a) throws IOException{
		        bw.write(String.valueOf(a));
		        bw.newLine();
		    }
		    public void print(double a) throws IOException{
		        bw.write(String.valueOf(a));
		    }
		    public void print(char a) throws IOException{
		        bw.write(String.valueOf(a));
		    }
		    public void println(char a) throws IOException{
		        bw.write(String.valueOf(a));
		        bw.newLine();
		    }
		}
	}

		

	

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值