【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

由于我们要求异或和 所以各个位不影响 不难想到 要转换成二进制做

 

example1

深蓝色的部分表示和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))

 

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 typedef long long ll;
 5 using namespace std;
 6 const ll N=20001,mo=1000000007;
 7 struct info{
 8     ll t,num,s;
 9     info(const ll a=0,const ll b=0,const ll c=0):
10         t(a),num(b),s(c){}
11 }im[N];
12 struct inas{
13     ll bo,x,y;
14     inas(const ll a=0,const ll b=0,const ll c=0):
15         bo(a),x(b),y(c){}
16 }ask[N];
17 ll n,m,f[N][13][2],sum[N][13],change[N];
18 char ch;
19 inline bool cmp(info a,info b){ return a.num<b.num; }
20 void makechange(){
21     sort(im+1,im+n+1,cmp);
22     for (ll i=1;i<=n;i++) change[im[i].t]=i;
23 }
24 void push(ll x,ll y,ll z){
25     ll now=im[x+1].s,nex=x+1,ney,nez,free;
26     for (ll i=0;i<10;i++)
27     if ((now>>i)&1){
28         if (i<y) ney=y,nez=z^((now>>y)&1),free=i;
29         if (i>y) ney=i,nez=sum[x][i],free=y;
30         if (i==y) ney=i,nez=z,free=i;
31         f[nex][ney][nez]=(f[nex][ney][nez]+(f[x][y][z]<<free)%mo)%mo;
32     }
33 }
34 void makef(ll t){
35     for (ll i=t-1;i<n;i++){
36         for (ll j=0;j<10;j++){
37             f[i+1][j][0]=f[i+1][j][1]=0;
38             sum[i+1][j]=sum[i][j]^((im[i+1].s>>j)&1);
39         }
40         for (ll j=0;j<10;j++)
41         for (ll k=0;k<=1;k++)
42         if (f[i][j][k]) push(i,j,k);
43     }
44 }
45 void print(ll t){
46     ll res=0;
47     for (ll i=9;i>=0;i--){
48         res=(res+f[n][i][(t>>i)&1])%mo;
49         if (sum[n][i]!=((t>>i)&1)) break;
50     }
51     printf("%I64d\n",res);
52 }
53 int main(){
54     scanf("%I64d%I64d",&n,&m);
55     for (ll x,i=1;i<=n;i++){
56         scanf("%I64d",&x);
57         im[i]=info(i,0,x+1);
58     }
59     for (ll i=1,x,y;i<=m;i++){
60         scanf("\n%c",&ch);
61         if (ch=='Q'){
62             scanf("%I64d",&x);
63             ask[i]=inas(0,x,0);
64         }else{
65             scanf("%I64d%I64d",&x,&y);
66             ask[i]=inas(1,x+1,y+1);
67             ++im[x+1].num;
68         }
69     }
70     makechange();
71     f[0][0][0]=1;
72     makef(1);
73     for (ll i=1;i<=m;i++)
74     if (ask[i].bo){
75         ll now=change[ask[i].x];
76         im[now].s=ask[i].y;
77         makef(now);
78     }else print(ask[i].x);
79 }
View Code

 

转载于:https://www.cnblogs.com/g-word/p/3482932.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信号去噪是数字信号处理中的一个重要问题,其目的是在尽量保留信号特征的前提下,去除信号中的噪声干扰。学者们在这个问题上进行了深入的研究,提出了多种方法。 1. 统计学方法 统计学方法主要是通过对信号和噪声的统计特性进行分析,设计滤波器来去除噪声。常用的方法包括中值滤波、均值滤波、小波变换、小波阈值去噪等。 参考资料: [1] Abrar H. Siddiqi, S. A. Samad, "Performance analysis of various denoising techniques for speech signals," International Journal of Electrical and Computer Engineering, vol. 2, no. 6, pp. 762-767, 2012. [2] N. Srinivasan, R. Rajaram, "Comparison of wavelet-based denoising techniques in ECG signals," Journal of Computer Science, vol. 7, no. 5, pp. 677-683, 2011. 2. 基于模型的方法 基于模型的方法是将信号看作某个模型的输出,通过对模型的优化来去除噪声。这种方法包括自适应滤波器、卡尔曼滤波器等。 参考资料: [1] J. M. Mendel, "Tutorial on higher-order statistics (spectra) in signal processing and system theory: theoretical results and some applications," Proceedings of the IEEE, vol. 79, no. 3, pp. 278-305, 1991. [2] J. K. Kim, S. H. Park, "Adaptive noise cancellation using a Kalman filter for speech enhancement," IEEE Transactions on Consumer Electronics, vol. 47, no. 3, pp. 564-570, 2001. 3. 深度学习方法 深度学习方法是近年来兴起的一种信号去噪方法。该方法通过训练神经网络来学习信号和噪声的特征,从而去除噪声。常用的方法包括自编码器、卷积神经网络等。 参考资料: [1] S. Zhang, Z. Zhang, Y. Li, "Denoising of power system transient signals using a deep convolutional neural network," IEEE Transactions on Power Delivery, vol. 31, no. 5, pp. 2176-2184, 2016. [2] K. Dabov, A. Foi, V. Katkovnik, K. Egiazarian, "Image denoising by sparse 3-D transform-domain collaborative filtering," IEEE Transactions on Image Processing, vol. 16, no. 8, pp. 2080-2095, 2007. 综上所述,信号去噪是一个重要的问题,学者们提出了多种方法。这些方法各有优缺点,需要根据具体情况选择合适的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值