【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],这 ...
随机推荐
- zoj 3777
状态压缩dp #include<cstdio> #include<cstring> #include<algorithm> #define maxn 4100 us ...
- 想要上市,SaaS 企业应该重点关注什么?(下)
前言:那些非常期待能在纳斯达克敲钟的 SaaS 服务提供商们,希望能从已经上市的「前辈」身上学到一些东西.对企业的销售主管来说,他们控制着影响整个公司长期收益的多个因素,同时,他们也对潜在投资者和金融 ...
- solr教程,值得刚接触搜索开发人员一看
http://blog.csdn.net/awj3584/article/details/16963525 Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍sol ...
- C: 数组形参
知识这个东西,真是知道的越多就不知道的越多,C/C++这塘水得多深啊,哈哈.看下面3个片段:<一> 1 void fun(char a[100]) { 2 fprintf( ...
- 【leetcode】Longest Common Prefix (easy)
Write a function to find the longest common prefix string amongst an array of strings. 思路:找最长公共前缀 常规 ...
- c++ 孟岩推荐 书籍
c++ primer 中文版本 是 教程+参考书 扛梁之作c++ 标准程序库 对于c++熟手来说更为快捷effective c++ 永远是初学者必读的,但是c++11标准后的第四版,还未发布c++ ...
- Nginx、LVS及HAProxy负载均衡软件的优缺点详解
http://www.csdn.net/article/2014-07-24/2820837
- python脚本工具-2 去除扩展名后提取目录下所有文件名并保存
文件夹里有多个RM格式的视频文件,现需要把它们的文件名都提取出来,并去掉文件的扩展名,以便放到需要的网页里. 源代码: # --- picknames.py --- import os filenam ...
- php/ java/asp.net
php大型网站用得多 企业级开发 java/asp.net用得多 这个很好理解 php 执行效率好 可塑性强 接近底层 java asp.net 封装了更多的东西,开发企业级业务 效率更高, 但是高性 ...
- 关于haproxy hdr_reg(host) 的一些解释
I've recently taken over an environment using HAProxy, and I'm attempting to learn the config and wh ...