【FOI】异或问题
题意:
给出n个数ai 和m个操作 操作有两种
C x y:将ax的值改为y
Q x:求几种方案使得 b1^b2^...^bn=x(ai>=bi)
题解:
先推荐一个不错的题解 题目差不多 我之前就是看着题解做的
http://hi.baidu.com/billdu/item/c749952ab2ab50c2ef10f137
首先我们先不考虑修改 即给你n个数ai 求几种方案使得异或和为x
为了方便起见 我们将原题的条件修改为0≤bi<ai 也就是原来的a数列中每一项都加1
由于我们要求异或和 所以各个位不影响 不难想到 要转换成二进制做

深蓝色的部分表示和ai的这一位一样
绿色部分表示ai的这一位是1 而这里是0的一位
橘黄色的部分表示不可以被随便确定的位 我们称其为“控制位”
而浅蓝色部分表示可以被随便确定的位
这种情况可能成为解的充要条件是没有橘黄色格子的列中的数异或起来和答案的这几位一样 答案显然是2^(浅蓝色格子数)
状态表示:
f[i][j][k]表示前i个数 1到j-1位有"控制位" 且第j位的异或和为k的方案数(这里的第一位是指最右边的一位)
转移:
为了方便 我们用递推的方法实现转移
对于 f[i][j][k] 枚举l 表示要将第i+1个数的第l位的1转换为0
令xo[i][j]表示前i个数第j位的异或和
当 l<j:nei=i+1,nej=j,nez=k^(第i+1个数的第j位),free=l-1
当 l==j:nei=i+1,nej=j,nez=k,free=l-1
当 l>j:nei=i+1,nej=l,nez=xo[i][l],free=j-1
f[nei][nej][nek]+=f[i][j][k]<<free
统计答案:
上面提到 一种状态成为解的充要条件是没有橘黄色格子的列中的数异或起来和答案的这几位一样
我们累加f[n][i][x的第i位] 直到xo[n][i-1]不等于x的第i-1位
修改:
用上面的方法每次修改都要把f数组重建 有1000次修改 每次O(n*log^2(1000)) 显然会tle
AK想到了一种机智的方法:
把可能变化的数放在数组的最后面 那么每次修改就最多只会影响后面的1000位
总的时间复杂度就大概是O(1000^2*log^2(1000))
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
const ll N=,mo=;
struct info{
ll t,num,s;
info(const ll a=,const ll b=,const ll c=):
t(a),num(b),s(c){}
}im[N];
struct inas{
ll bo,x,y;
inas(const ll a=,const ll b=,const ll c=):
bo(a),x(b),y(c){}
}ask[N];
ll n,m,f[N][][],sum[N][],change[N];
char ch;
inline bool cmp(info a,info b){ return a.num<b.num; }
void makechange(){
sort(im+,im+n+,cmp);
for (ll i=;i<=n;i++) change[im[i].t]=i;
}
void push(ll x,ll y,ll z){
ll now=im[x+].s,nex=x+,ney,nez,free;
for (ll i=;i<;i++)
if ((now>>i)&){
if (i<y) ney=y,nez=z^((now>>y)&),free=i;
if (i>y) ney=i,nez=sum[x][i],free=y;
if (i==y) ney=i,nez=z,free=i;
f[nex][ney][nez]=(f[nex][ney][nez]+(f[x][y][z]<<free)%mo)%mo;
}
}
void makef(ll t){
for (ll i=t-;i<n;i++){
for (ll j=;j<;j++){
f[i+][j][]=f[i+][j][]=;
sum[i+][j]=sum[i][j]^((im[i+].s>>j)&);
}
for (ll j=;j<;j++)
for (ll k=;k<=;k++)
if (f[i][j][k]) push(i,j,k);
}
}
void print(ll t){
ll res=;
for (ll i=;i>=;i--){
res=(res+f[n][i][(t>>i)&])%mo;
if (sum[n][i]!=((t>>i)&)) break;
}
printf("%I64d\n",res);
}
int main(){
scanf("%I64d%I64d",&n,&m);
for (ll x,i=;i<=n;i++){
scanf("%I64d",&x);
im[i]=info(i,,x+);
}
for (ll i=,x,y;i<=m;i++){
scanf("\n%c",&ch);
if (ch=='Q'){
scanf("%I64d",&x);
ask[i]=inas(,x,);
}else{
scanf("%I64d%I64d",&x,&y);
ask[i]=inas(,x+,y+);
++im[x+].num;
}
}
makechange();
f[][][]=;
makef();
for (ll i=;i<=m;i++)
if (ask[i].bo){
ll now=change[ask[i].x];
im[now].s=ask[i].y;
makef(now);
}else print(ask[i].x);
}
【FOI】异或问题的更多相关文章
- Android数据加密之异或加密算法
前言: 这几天被公司临时拉到去做Android IM即时通信协议实现,大致看了下他们定的协议,由于之前没有参与,据说因服务器性能限制,只达成非明文传递,具体原因我不太清楚,不过这里用的加密方式是采用异 ...
- Oracle数据库异机升级
环境: A机:RHEL5.5 + Oracle 10.2.0.4 B机:RHEL5.5 需求: A机10.2.0.4数据库,在B机升级到11.2.0.4,应用最新PSU补丁程序. 目录: 一. 确认是 ...
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- [PHP][位转换积累]之异或运算的简单加密应用
异或的符号是^.按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0. xor运算的逆运算是它本身,也就是说两次异或同一个数 ...
- Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5646 Accepted: 1226 Description In an ...
- RMAN异机恢复遭遇ORA-01547、ORA-01152、ORA-01110错误案例
测试环境: 操作系统 : Red Hat Enterprise Linux ES release 4 (Nahant Update 4) VMWARE 数据库 : O ...
- RAC异机恢复
RAC异机恢复PDCL到PFCL: PNCL:RAC+ASM ,product env db name:PNCL instance:PDCL1 PDCL2 PFCL:RAC+ASM ,perf ...
- BZOJ 3261: 最大异或和
Description 一个序列,支持两个操作. 1.在序列尾加入一个数. 2.询问 [l,r] 中与 x 异或值最大的数. \(n\leqslant 3*10^5\) Sol 可持久化 Trie 树 ...
- 异或之(bzoj 3689)
Description 给定n个非负整数A[1], A[2], --, A[n].对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这 ...
随机推荐
- JavaScript 踩坑心得— 为了高速(上)
一.前言 很多情况下,产品的设计与开发人员一直想打造一套高品质的解决方案,从而快速.平稳地适应产品迭代.速度是衡量产品适应性的真正且唯一的标准,而且,这并不是笔者的一家之言. 「速度是衡量适应能力的真 ...
- 【leetcode】4Sum(middle)
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...
- Kafka操作
http://blog.csdn.net/xiao_jun_0820/article/details/46831203 http://blog.csdn.net/xcockroach/article/ ...
- vs 下 opengl 配置问题
项目 -->选择属性 C\C++-->preprocessor-->preprocessor definition 添加GLUT_BUILDING_LIB,中间用分号隔开. 然后点击 ...
- php实现自动运行文件
autoexec.php <?php ignore_user_abort(); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行. set_time_limit(30); // ...
- centos 搭建 darwin calendar 服务器
方法一(官网方法): useradd caluser ----为日历服务器建立一个新用户,方便管理 passwd caluser -----新用户更改密码 su caluser mkdir ~/Cal ...
- hdu 4502 吉哥系列故事——临时工计划(dp)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4502 思路:一个简单的dp ,比赛时没做出来呢..... d[i]代表 到第i天时的最大值 #includ ...
- LeetCode Excel Sheet Column Title (输出excel表的列名称)
题意:给一个数字n,输出excel表的列名称. 思路:其实观察可知道,是个26进制的标记而已.那就模拟一下,每次计算一位时就先左移1位,再进行计算. class Solution { public: ...
- 网站资料收集 主要查看js的学习部分
1.Asp.Net MVC3.0基本的简单的可能都会用,更深入的使用还需加深研究,之后希望对MVC4.0和5.0进行对比学习,暂时看到@葡萄城控件技术团队博客的MVC5系列正在继续http://www ...
- 在 Azure 中使用公用 IP 创建多 NIC VM
Russ Slaten 2014年 11 月 18日下午 4点 我们最近宣布了支持具有多个网络接口控制器 (NIC) 的虚拟机 (VM).我仍在努力了解此功能适用的所有新场景,但首先,我希望亲自测试 ...