题目链接
Fixed Point Time Limit: 2 Seconds Memory Limit: 65536 KBIn mathematics, a fixed point (sometimes shortened to fixpoint, also known as an invariant point) of a function is an element of the function's domain that is mapped to itself by the function. A set of fixed points is sometimes called a fixed set. That is to say, c is a fixed point of the function f(x) if and only if f(c) = c. This means f(f(...f(c)...)) = fn(c) = c, an important terminating consideration when recursively computing f. For example, if f is defined on the real numbers by f(x) = x2 - 3x + 4, then 2 is a fixed point of f, because f(2) = 2.
Bob has three funtions define on nonegative integers, A(x) = c ∧ x, E(x) = c ⊕ x, and O(x) = c ∨ x, where ∧ means bitwise AND operation, ⊕ means bitwise XOR operation, ∨ means bitwise OR operation and c is an integer constant.
Bob wants to know the number of fixed points for each function which satisfy the following conditions:
You are given three integers L, R and k, please tell Bob the answer.
Note: x is a 32-bit integer, that is x's binary representation only has 32 bits.
The first line of input contain an integer T (T ≤ 10000), which is the number of cases.
Then next T line, each line contain four integers L, R, c and k (0 ≤ L ≤ R < 232, 0 ≤ c < 232, 0 ≤ k ≤ 32), separated by spaces.
For each test case, print a line containing the test case number (beginning with 1) followed by three integers, indicating the number of fixed points for function A(x), E(x) and O(x), separated by one space.
3 1 10 1 32 1 100 43 32 1 200 43 20
Case 1: 1 0 5 Case 2: 15 0 4 Case 3: 0 0 7
题意:A(x)=c&x, B(x)=c^x,C(x)=c|x。分别求出在[L,R]的范围内,满足A(x)=x,B(x)=x,C(x)=x,且32位二进制表示中1的个数和0的个数的差的绝对值小于等于k的数的个数。
题解:由于数的范围较大,所以要用数位统计的方法。先将数转换到二进制。用dp[i][j] 表示从32位到第i位的数,二进制0,1的绝对值之差为j,由当前状态变到目标状态的数的个数。转移的时候分别满足A(x)=x,B(x)=x.C(x)=x的条件。
代码如下:
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<string> #include<stack> #include<math.h> #include<vector> #include<set> #include<map> #define nn 110000 #define inff 0x7fffffff #define eps 1e-8 #define mod 1000000007 typedef long long LL; const LL inf64=LL(inff)*inff; using namespace std; LL l,r,c,k; LL wc[40]; LL wei[40]; LL dp[40][70]; LL dfs(int id,int s,int ty,bool man) { if(id==-1) { if(abs(s-35)<=k) return 1; return 0; } if(!man&&dp[id][s]!=-1) return dp[id][s]; int end=man?wei[id]:1; LL re=0; for(int i=0;i<=end;i++) { if(ty==1) { if((wc[id]&i)==i) { if(i==0) re+=dfs(id-1,s-1,ty,man&&i==end); else re+=dfs(id-1,s+1,ty,man&&i==end); } } if(ty==2) { if((wc[id]^i)==i) re+=dfs(id-1,i==0?(s-1):(s+1),ty,man&&i==end); } if(ty==3) { if((wc[id]|i)==i) re+=dfs(id-1,i==0?(s-1):(s+1),ty,man&&i==end); } } if(!man) dp[id][s]=re; return re; } LL solve(LL x,int ty) { int ix=0; memset(wei,0,sizeof(wei)); while(x) { wei[ix++]=x%2; x/=2; } return dfs(31,35,ty,true); } int main() { int t,cas=1; scanf("%d",&t); while(t--) { scanf("%lld%lld%lld%lld",&l,&r,&c,&k); LL ans1,ans2,ans3; int ix=0; LL ic=c; memset(wc,0,sizeof(wc)); while(c) { wc[ix++]=c%2; c/=2; } if(l==0) { memset(dp,-1,sizeof(dp)); ans1=solve(r,1); memset(dp,-1,sizeof(dp)); ans2=solve(r,2); memset(dp,-1,sizeof(dp)); ans3=solve(r,3); } else { memset(dp,-1,sizeof(dp)); ans1=solve(r,1)-solve(l-1,1); memset(dp,-1,sizeof(dp)); ans2=solve(r,2)-solve(l-1,2); memset(dp,-1,sizeof(dp)); ans3=solve(r,3)-solve(l-1,3); } printf("Case %d: ",cas++); printf("%lld %lld %lld\n",ans1,ans2,ans3); } return 0; }