码迷,mamicode.com
首页 > 其他好文 > 详细

CF241D

时间:2019-03-02 13:41:27      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:通过   就是   git   pac   write   .com   class   图片   情况   

技术图片

题目大意:

给你n个数和p,都小于50000要求留下若干个数字,使得剩下的数字异或为0,并且从左到右串联起来可以被p整除,求一种这样的方案。

搜索

我们无视排列中所有>25的元素。因为由1~25组成的异或和为0的方案有1<<20 == 1048576个,已经远大于50000。在这么多种方案下,一个序列拼起来模p几乎可以看作是一个随机函数,异或和为0跟拼起来模p等于0之间几乎没有相关性。那也就是说我们在1~25之内找不到合法解的概率是 (4999950000)1048576≈7.8∗10−10(4999950000)1048576≈7.8∗10−10

假设只考虑所有≤2l2l的数,那么由1∼2l1∼2l组成的异或和为 00 的方案大约会有 22l2l22l2l 个。即总方案数 22l22l,除以总的结果方案数 2l2l(答案为0的只有12l12l 概率)

在如此大概率能找到解的情况下,可以通过本题。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read () { LL res = 0 ;int f (1) ;char ch = getchar ();
    while (!isdigit(ch)) { if (ch == -) f = -1 ;ch = getchar();}
    while (isdigit(ch)) res = (res << 1) + (res << 3) + (ch ^ 48) ,ch = getchar(); return res * f ;
}
template<class T>void write(T x){
  if(x>9) write(x/10);
  putchar(48+x%10);
}
int const maxn=1<<5;
int n,p,a[maxn],b[maxn],m,check,pos[maxn];
int inline pw(int x){
  return x<10? 10:100;
}
inline void dfs(int k,int x,int y,int num){
  if(x==0 and y==0 and num){
    puts("Yes"); write(num);putchar(\n);
    for(register int i=1;i<=num;i++) write(b[i]),putchar( ); exit(0);
  }
  if(k>m) return ;
  dfs(k+1,x,y,num);
  b[num+1]=pos[a[k]];
  dfs(k+1,x^a[k],(y*pw(a[k])+a[k])%p,num+1);
}
signed main () {
    n=read(),p=read();
    for(register int i=1;i<=n;i++) {
        int x=read();
        if(x<maxn) a[++m]=x,pos[x]=i;
    }
    dfs(1,0,0,0); puts("No");
    return 0;
}

 

CF241D

标签:通过   就是   git   pac   write   .com   class   图片   情况   

原文地址:https://www.cnblogs.com/qf-breeze/p/10460727.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!