题解 big
题面里那个式子
考场上我推了半天那个式子代表什么意思,但就是没想到位运算
\(\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的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- TransE 算法学习笔记
http://yaoleo.github.io/2017/10/27/TransE算法的理解/ tranE是在模型中嵌入知识图谱等三元组类的一个方法,就像是句子利用词典嵌入一样.
- python 字典添加数据
dzkuaa={}#类似{"张三":2,"李四":3} for i in range(23): ming=bj[i] if dzkuaa.get(ming)== ...
- 每天五分钟Go - 常量
常量的声明 常量使用const进行对不会被改变值的修饰符 const 常量名 [常量类型] = 常量值,和变量的声名一样可以省略类型 const a=1 const b="a" c ...
- bootstrap与vue的区别是什么?(十七)
Bootstrap Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍的前端开发框 ...
- Jmeter 学习笔记 1 - Logic Controller -组织执行场景
using this website to practice performance testing: http://advantageonlineshopping.com/#/ Jemeter ho ...
- python errno库与socket.connect_ex()方法的结合使用
前言:一般socket链接会首选connect方法,该方法会一直尝试链接.那么今天展示下connect_ex()方法,该方法如果链接成功会返回0,失败会返回errno库中的errorcode中的key ...
- ECShop 2.x/3.x SQL注入/任意代码执行漏洞
poc地址:https://github.com/vulhub/vulhub/blob/master/ecshop/xianzhi-2017-02-82239600/README.zh-cn.md 生 ...
- Android 帧动画使用
帧动画 使用一系列不同的图片,然后像一卷胶卷一样按顺序播放,这是一种传统的动画,也可称为帧动画.也可以比喻为像一卷胶卷一样按顺序播放. 播放起来,有点像在看gif图. 本文介绍使用AnimationD ...
- 组合数取模(lukas)板子
求 C(n,m)%mo #include<bits/stdc++.h>#define re register int#define mo 10007#define ll long long ...
- 剑指 Offer 29. 顺时针打印矩阵
剑指 Offer 29. 顺时针打印矩阵 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出: ...