【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],这 ...
随机推荐
- 关于Java中try-catch-finally-return语句的思考
我们知道return语句用在某一个方法中,一是用于返回函数的执行结果,二是用于返回值为void类型的函数中,仅仅是一个return语句(return ;),此时用于结束方法的执行,也即此return后 ...
- POJ 1850 Code(组合数)
http://poj.org/problem?id=1850 题意 :给定字符串,系统是用字符串组成的,字符串是按字典序排的.编码系统有三条规则,1这些的单词的长度是由小到大的,2相同长度的按字母在字 ...
- 在线学习SQL语句?没问题~~
以前弄得少,没注意.. http://sqlfiddle.com/ CREATE TABLE Presidents ( Id INT UNSIGNED NOT NULL AUTO_INCREMENT, ...
- 李洪强iOS开发之自定义cell的使用
第一步: 创建自定义cell类,继承自UItableVIewcell 第二步: 在sb中布局自己需要的视图控件并且将此cell与我刚刚创建的cell类进行关联.并且连线 第三步: 创建modle类, ...
- 利用PyInstaller将python代码封装成EXE(亲测可用)
有些不能成功,有些不全的,下面总结一下,给自己以后看看. 1下载PyInstaller..去官网下载http://www.pyinstaller.org/(我下载的版本) 2不需要安装,解压即 ...
- android从应用到驱动之—camera(1)---程序调用流程[转]
一.开篇 写博客还得写开篇介绍,可惜,这个不是我所擅长的.就按我自己的想法写吧. 话说camera模块,从上层到底层一共包含着这么几个部分: 1.apk------java语言 2.camera的ja ...
- Git教程(7)用合并还是变基?
合并或变基前的样子:分支experiment与master两个分支都产生了提交. 图1. 未合并或变基前的样子 合并 原理: 找到两个分支的最末提交和最近的共同祖先,在执行git merge时所处的分 ...
- Android开发之自定义组合控件
自定义组合控件的步骤1.自定义一个View,继承ViewGroup,比如RelativeLayout2.编写组合控件的布局文件,在自定义的view中加载(使用View.inflate())3.自定义属 ...
- Python中的抽象超类
# -*- coding:utf-8 -*- class Super(object): def test(self): self.action() class Sub(Super): def acti ...
- CQOI2011分金币&HAOI2008糖果传递
双倍经验…… 没想到白书上竟然有……我还看过……还忘了…… 抄份题解: A1 + X1 - X2 = G A2 + X2 - X3 = G . . . An + Xn - X1 = G 解得 X1 = ...