hdu5715 XOR 游戏 [2016百度之星复赛D题]

   比赛的时候没仔细想,赛后一想这题其实挺简单的,先求出序列的异或前缀和,然后将异或前缀和建出一颗trie树,然后我们可以二分答案,把问题变成判定性问题,判定是否存在一种方案,使得所有的分组的异或和都大于等于这个二分的答案,然后就可以dp了,用f[i][j]表示到j为止能不能分成i组,f[i][j]=f[i-1][j-k]|f[i-1][j-k+1]...|f[i-1][j-1],这个东西用trie树维护一下就可以了。单组数据复杂度O(nmlogn^2)

  代码

 1 #include<cstdio>
 2 const int N = 1001010;
 3 int num[N],Num[N],trie[N][2],tt,sum[N];
 4 int n,m,l,r,i,k,j,a[N],mid;
 5 int flag[11][N];
 6 void add(int x,int y)
 7 {
 8     int i;
 9     for (i=0;i<=31;i++)
10     num[i]=x&1,x>>=1;
11     int t=0;
12     for (i=31;i>=0;i--)
13     {
14         if (trie[t][num[i]]==0) trie[t][num[i]]=++tt;
15         t=trie[t][num[i]];
16         sum[t]+=y;
17     }
18 }
19 int find(int x,int y)
20 {
21     int i;
22     for (i=0;i<=31;i++)
23     {
24         num[i]=x&1,x>>=1;
25         Num[i]=y&1,y>>=1;
26     }
27     int t=0;
28     for (i=31;i>=0;i--)
29     {
30         if (Num[i]==1)
31         {
32             if (!sum[trie[t][1-num[i]]]) return 0;
33             else t=trie[t][1-num[i]];
34         }
35         else
36         {
37             if (sum[trie[t][1-num[i]]]) return 1;
38             else if (!sum[trie[t][num[i]]]) return 0;
39             else t=trie[t][num[i]];
40         }
41     }
42     return 1;
43 }
44 int check(int x)
45 {
46     int i,j;
47     for (i=0;i<=m;i++)
48     for (j=0;j<=n;j++)
49     flag[i][j]=0;
50     flag[0][0]=1;
51     for (i=1;i<=m;i++)
52     {
53         for (j=0;j<=tt;j++) sum[j]=0;
54         for (j=0;j<=n;j++)
55         {
56             if (j-k-1>=0)
57             if (flag[i-1][j-k-1]) add(a[j-k-1],-1);
58             flag[i][j]=find(a[j],x);
59             if (flag[i-1][j]) add(a[j],1);
60         }
61     }
62     return flag[m][n];
63 }
64 int main()
65 {
66     int test;
67     scanf("%d",&test);
68     for (int ii=1;ii<=test;ii++)
69     {
70     for (i=0;i<=tt;i++)
71     trie[i][0]=trie[i][1]=0;
72     tt=0;
73     scanf("%d%d%d",&n,&m,&k);
74     for (i=1;i<=n;i++)
75     {
76         scanf("%d",&a[i]);
77         a[i]^=a[i-1];
78     }
79     for (i=0;i<=n;i++)
80     add(a[i],0);
81     l=1;r=2000000000;
82     while (l<=r)
83     {
84         mid=(l+r)>>1;
85         if (check(mid)) l=mid+1;else r=mid-1;
86     }
87     printf("Case #%d:\n",ii);
88     printf("%d\n",r);
89     }
90 }
时间: 2024-12-23 15:27:31

hdu5715 XOR 游戏 [2016百度之星复赛D题]的相关文章

hdu5713 K个联通块[2016百度之星复赛B题]

dp 代码 1 #include<cstdio> 2 const int N = 30000; 3 const int P = 1000000009; 4 int n,m,k,cnt[N]; 5 long long f[N],g[N],o[N],dp[N][15]; 6 int e[15][15],i,j,l,a,b; 7 int check(int x,int y) 8 { 9 int i; 10 for (i=0;i<n;i++) 11 if ((1<<i)==x) br

hdu5714 拍照[2016百度之星复赛C题]

由于船移动的速度都一样,那么对于往一个方向的船相对距离其实是不变的,我们可以把往一个方向移动的船都视作静止,并求出在哪些观测位置可以看到,很明显对于船[x,y,z],当x+z>=y-z的时候,可以在[y-z,x+z]这些位置观测到它,这些位置的观测数全都+1,然后考虑不同方向,假设初始在x位置观测往右的船,在y位置观测到往左的船,只要x<=y,则经过一段时间的移动,必然存在一个位置可以同时观测到x位置和y位置能观测到的船.复杂度O(nlogn). 代码 1 #include<cstdio

2016百度之星复赛 1003 拍照 优先队列

2016"百度之星" - 复赛(Astar Round3) Ended 2016-05-29 14:00:00 - 2016-05-29 17:00:00 Current Time: 00:46:02 Solved Pro.ID Title Ratio(Accepted / Submitted) Language   1001 D++游戏 13.79% (16/116) 中文   1002 K个联通块 17% (136/800) 中文 1003 拍照 22.49% (434/1930)

2016&quot;百度之星&quot; - 复赛(Astar Round3) 1003 拍照

拍照 思路:先静态,离线树状数组,分别统计每个点向左向右能看到的船的数量.再枚举整个区间求最大值. 应为人和船都是动态的,假设船往左走,处理每个点看到向左最大船的数量,满足动态条件.就是向左的船一开始在最右边,向右的船一开始在最左边,则两船肯定相向运动到某个地方最佳. 1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交 2 #include <cstdio> 3 #include <cs

2016 百度之星 复赛 - 拍照

小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行.小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中. 小明位于河的边上,并且可以在河边的任意位置进行拍照,照相机的视野恰好为90度角,只能以垂直于河边的方向进行拍照.河上的船只全都可看作是平行于河边的一条线段,跟河边的距离各不相同,有的正在向左移动,有的正在向右移动,但移动速度恰好都是一样的.小明可以等待恰当的时间让尽量多的船只都走进照相机的视野里,你不需要考虑船只之间会互相遮挡视野的情况

2016百度之星 补题记

2016"百度之星" - 复赛(Astar Round3) 拍照 思路:先把所有的线段投影到x轴,然后将所有线段的起末坐标存进数组,排序后从坐标最小开始枚举.如果遇到起点标志,就加一:结束点标志减一.如此即可求出同一时刻,遇到当前线段结束点时,有多少线段包含在内 /************************************************************** Problem:hdu 5417 User: youmi Language: C++ Result

2014百度之星第三题Xor Sum

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 4445    Accepted Submission(s): 652 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

2016百度之星总结帖

2016百度之星总结帖 测试赛 选的2015资格赛的部分题目,第二题字符串处理,第三题map计数 1001 大搬家 f f (x) = x 两次置换后回到原位 dp a->b && b->a,考虑n个数 如果它独自成对,那么就有s[n-1]: 如果它与前面某个成对,首先可以有n-1个可取,然后每个都有s[n-2]: 故s[n] = s[n-1] + (n-1)s[n-2]; 1004 放盘子 今天他向来访者们提出一个恶俗的游戏.他和来访者们轮流往一个正多边形内放盘子.最后放盘子

2016&quot;百度之星&quot; - 资格赛(Astar Round1) Problem D 简单题

Problem D Accepts: 1527 Submissions: 4307 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如,如果一个人名字