传送门

题面里那个式子

考场上我推了半天那个式子代表什么意思,但就是没想到位运算

\(\lfloor \frac{2x}{2x^n} \rfloor \iff x\gg(n-1)\), 即将x的第n位移至最低位

\(2*x\%2^n \iff (x\ll 1)\%2^n\), 即将x左移一位并舍弃n+1及更高位

所以这两个操作等价于将x循环左移一位,最高位补至最低位

显然那一大串异或操作可以搞个前缀和

然后考虑何时取最大值

先说一个错误的思路 我考场上打的暴力就是这么挂的

令\(sum[i]\)为前i次操作的异或和

\(x \in [0, 2^n)\)可以取遍二进制位的所有情况,

所以 \(x \oplus sum[i] \in [0, 2^n)\)

那么x异或上前i个数就等价于没异或,题目就转化为求这i个数异或后缀和的最大值

然后你会在测样例的时候面对着一个执着的3一筹莫展

这个做法错误的原因是没有满足「你的对手会使 x 最后尽量小」

也就是说,你的对手会在你确定x后找到会使一个最小的位置下手

而我们先固定下手位置,再确定x的做法就显然不对了

再说正解:

令\(suf[i]\)为异或后缀和(suf为suffix缩写)

因为异或时各位互不影响的特性,x异或上前i个数等价于循环移位后的x异或上前i个数循环移位后的结果

那么令\(sum[i]\)为前i个数循环移位后的异或前缀和

题面就转化为求一个\(x\)使\(x \oplus sum[i] \oplus suf[i+1]\)最大

就珂以扔到一棵trie树上跑了

p.s. 这题还有一个坑点是求「得到最大值的初值数量」,实际上指的是有多少个不同的x能取到这个最大值,而不是指有多少个位置i能取到最大值. 哦这就是我一调一小时的原因

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define ld long double
#define usd unsigned
#define ull unsigned long long
//#define int long long #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
char buf[1<<21], *p1=buf, *p2=buf;
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
} int n, m;
int a[N], sum[N], suf[N], size;
struct trie{
int son[2], cnt;
#define t(p) tree[p]
}tree[N*25]; void upd(int u) {
int p=0, t, t2;
for (int i=30; i>=0; --i) {
t2 = (u&(1<<i))?1:0;
t = t(p).son[t2];
if (!t) {t(p).son[t2]=++size; t=size;}
p = t;
}
t(p).cnt = 1;
} int query(int dep, int p) {
if (dep<0) return 0;
if (t(p).son[0] && t(p).son[1]) {
int t1=query(dep-1, t(p).son[0]), t2=query(dep-1, t(p).son[1]);
if (t1==t2) t(p).cnt = t(t(p).son[0]).cnt+t(t(p).son[1]).cnt;
else t(p).cnt += t1>t2?t(t(p).son[0]).cnt:t(t(p).son[1]).cnt;
return max(t1, t2);
}
else {
if (t(p).son[0]) {
int t=query(dep-1, t(p).son[0])|((dep<n)?(1<<dep):0);
t(p).cnt += t(t(p).son[0]).cnt;
return t;
}
else {
int t=query(dep-1, t(p).son[1])|((dep<n)?(1<<dep):0);
t(p).cnt += t(t(p).son[1]).cnt;
return t;
}
}
} int query_cnt(int u) {
int p=0;
for (int i=30; i; --i)
p = (u&(1<<i))?t(p).son[1]:t(p).son[0];
//cout<<p<<endl;
return t(p).cnt;
} signed main()
{
#ifdef DEBUG
freopen("1.in", "r", stdin);
#endif n=read(); m=read();
for (int i=1; i<=m; ++i) a[i]=read(), sum[i]=sum[i-1]^(((a[i]>>(n-1))+(a[i]<<1))%(1<<n));
//for (int i=1; i<=m; ++i) a[i]=read(), sum[i]=sum[i-1]^((a[i]<<1)%(1<<(n-1)));
for (int i=m; i; --i) suf[i] = suf[i+1]^a[i];
for (int i=0; i<=m; ++i) upd(sum[i]^suf[i+1]); //, cout<<"upd "<<(sum[i]^suf[i+1])<<endl;
int t=query(30, 0);
printf("%d\n%d\n", t, t(0).cnt); return 0;
}

题解 big的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. ArchLinux安装步骤(一)

    本文为安装archlinux的教程,需要有硬盘分区,挂载等基础linux命令的了解还有vim的基本操作,不知道也没关系,这里有大神的视频教程ArchLinux指南. 确实是不是uefi模式 ls /s ...

  2. python 17篇 unittest单元测试框架

    单元测试:开发程序的人自己测试自己的代码 unittest自动化测试框架 1.单元测试 import unittest def add(a,b): return a+b # 在运行时不要用run un ...

  3. Linux常用基础命令(二)

    Linux常用基础命令 一.-ls--列表显示目录内容 二.-alias--设置别名 三.-du--统计目录及文件空间占用情况 四.-mkdir--创建新目录 五.-touch--创建空文件 六.-l ...

  4. JPA用法中字段起名规范

    前两天在学习Springboot使用JPA 来操作数据库时,碰到一个问题,最终发现了JPA写法中表字段名称要写规范. 记录下来提醒自己. CityEntity是一个City的实体类. 1 @Table ...

  5. urllib3使用池管理发送请求和requests常用方法的基本使用+session使用

    使用urllib3的池管理器 urllib3是在urllib进行更加深入的改进,最大的好处就是在urllib的基础上添加了池管理,以至于我们不需要再去注意我们需要由那个链接去发送请求,而只需要获取到链 ...

  6. python框架之Flask

    介绍:Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . WSGl:Web Server Gateway ...

  7. kali操作系统安装google浏览器

    安装的kali操作系统版本是kali-linux-2020.2-installer-amd64.iso 参考链接:https://www.cnblogs.com/Young-wind/p/585502 ...

  8. Skywalking-04:扩展Metric监控信息

    扩展 Metric 监控信息 官方文档 Source and Scope extension for new metrics 案例:JVM Thread 增加 Metrics 修改 Thread 的定 ...

  9. Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)

    Apache Tomcat 7.0.0~7.0.79 直接发送以下数据包即可在Web根目录写入shell: PUT /1.jsp/ HTTP/1.1 Host: 192.168.49.2:8080 A ...

  10. 移植TensorFlow到Windows平台

    2015年11月,Google宣布开源旗下机器学习工具TensorFlow,引发业界热潮.TensorFlow原生支持*unix系和安卓平台,但并不提供对Windows平台的支持.如果想在Window ...