【WC2015模拟2.6】Circle
来源:互联网 发布:mac系统软件卸载 编辑:程序博客网 时间:2024/05/16 07:35
Description
一开始有个n个在[0,2^m)区间内的数。
每一秒每一个数将会+1,然后对2^m取模。
求在[1,T]秒内,有多少个时间,使得这n个数的异或值为S。
n<=10^5,m<=50,T<=10^16
Solution
很显然的与位运算有关的题目。
首先我们就相当于求给出一个上界up,[1,up]中有多少个数x使得所有的(ai+x)%2^m的异或值为S。
考虑Dp,发现我们只需要二进制的后m位的异或值与S相同,这样就不用考虑%的问题。
但是发现加法会产生进位,比较难处理。
考虑设状态Fi,j,0\1表示后i-1位已经确定了,第i-1位向第i位产生了j个进位,0\1表示加的数和上界的关系
我们可以发现,因为加的数一样,这j个进位一定是后i-1位最大的那j个数所产生的。
那么我们可以预处理对于每个i,j,产生进位的是哪些数。
我们只需要对这n个值排序就好了,排m次。
排序的考虑类似基数排序,从上一次排序的结果O(N)推出这一次的排序结果。
然后转移分情况讨论就好了,转移比较复杂,详细见代码。
一道好题,(⊙v⊙)嗯。
Code
#include <cstdio>#include <cstring>#include <algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;typedef long long ll;const int N=1e5+5,M=55;int n,m,d[M];ll t,s,cnt,a[N],mi[M],f[M][N][2],c[M][N];bool cmp(ll x,ll y) {return x>y;}ll dp(ll upper) { memset(f,0,sizeof(f));f[0][0][0]=1; fo(i,0,m-1) fo(up,0,1) { int ad=d[i],k=0,x; fo(j,0,n) { if (f[i][j][up]) { if ((s&mi[i])&&(ad&1)||!(s&mi[i])&&!(ad&1)) { if (!(upper&mi[i])&&up) x=1;else x=0; f[i+1][k][x]+=f[i][j][up]; } if ((s&mi[i])&&((n-ad)&1)||!(s&mi[i])&&!((n-ad)&1)) { if ((upper&mi[i])&&!up) x=0;else x=1; f[i+1][k+ad][x]+=f[i][j][up]; } } if (i&&j<n) { if (a[c[i-1][j+1]]&mi[i]) k++,ad--; else ad++; } } } ll ans=0; fo(i,0,n) ans+=f[m][i][0]; return ans;}int main() { scanf("%d%d%lld%lld",&n,&m,&s,&t);cnt=s; fo(i,1,n) scanf("%lld",&a[i]),cnt^=a[i]; mi[0]=1;fo(i,1,m+1) mi[i]=mi[i-1]*2; fo(j,0,m-1) { fo(i,1,n) d[j]+=(a[i]&mi[j])>0; if (j) { int tot=0; fo(i,1,n) if (a[c[j-1][i]]&mi[j]) c[j][++tot]=c[j-1][i]; fo(i,1,n) if (!(a[c[j-1][i]]&mi[j])) c[j][++tot]=c[j-1][i]; } else { int tot=0; fo(i,1,n) if (a[i]&1) c[j][++tot]=i; fo(i,1,n) if (!(a[i]&1)) c[j][++tot]=i; } } printf("%lld\n",t/mi[m]*dp(mi[m]-1)+dp(t%mi[m])-(cnt==0));}
0 0
- 【WC2015模拟2.6】Circle
- JZOJ 3988 【WC2015模拟2.6】Circle
- 【WC2015模拟2.6】Tree
- JZOJ 3987 【WC2015模拟2.6】Tree
- ZOJ 3321 Circle【模拟】
- WC2015 记
- 记WC2015
- Hrbust 2313 Circle Fan【模拟+思维】
- circle ``
- Circle
- circle
- WC2015简短感想
- July 17th 模拟赛C T3 Circle Solution
- Wc2015……酱油记?
- UOJ 73 [WC2015]未来程序
- GDOI'2016模拟day1 —— 大水题(就是这个名字)(circle)
- WC2015总结&解题报告(伪)
- circle pendants
- spark 存储管理
- Android自定义TextView闪烁文字的效果
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- 练习
- Linux内核中断机制(二):异常向量表建立
- 【WC2015模拟2.6】Circle
- linux之路由知识之ip route 命令中的疑惑
- poj 3368 Frequent values
- 使用SublimeText 作为Python 的开发环境
- UVALive7220
- 简单好用的上拉加载下拉刷新 BaseRecyclerViewAdapterHelper
- linux初学<习题二>如何打开一个bash?
- Digimat-MF:平均场均匀化——(五)方向张量
- Swift学习之集合的reduce 操作详解