bzoj 2992: Pku3986 Math teacher's homework 数位dp

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33229466/article/details/79980855

题意

给出两个整数K,N和一个整数序列M1,M2…Mn
求满足X1 Xor X2 Xor X3…Xor Xn=k且0<=Xi<=Mi(i=1…n)的解的个数
1n50,0k,m1,m2mn2311

分析

我们按从高到底位进行处理。
假设前i位都已经处理好了,若存在一个数x[t],满足前i位中某一位比M[t]要小,那么x[t]剩下的位就可以随便填。
既然这样,那么我们就可以先不填x[t],然后让剩下的数随便填,设其最终异或和为w,那么我们只要在x[t]填上w Xor K,则可以得到一组解。
也就是说若存在一位满足其已经没有大小的限制了,那么剩下的就可以随便填。
考虑枚举这是哪一位,再枚举该位第一个没有限制的数,剩下的位置只要dp一下就好了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

typedef long long LL;

const int N=55;
const int MOD=1000000003;

int n,m,bin[25],f[N][2],a[N];

int main()
{
    bin[0]=1;
    for (int i=1;i<=30;i++) bin[i]=bin[i-1]*2;
    scanf("%d%d",&n,&m);
    while (n||m)
    {
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        int ans=0;
        for (int i=30;i>=0;i--)
        {
            for (int j=1;j<=n;j++)
            {
                if (!(a[j]&bin[i])) continue;
                int s=1,c=0;
                for (int k=1;k<j;k++) s=(LL)s*(a[k]%bin[i]+1)%MOD,c^=((a[k]&bin[i])>0);
                f[j][c]=s;f[j][c^1]=0;
                for (int k=j+1;k<=n;k++)
                    if (a[k]&bin[i])
                    {
                        f[k][0]=((LL)f[k-1][1]*(a[k]%bin[i]+1)%MOD+(LL)f[k-1][0]*bin[i]%MOD)%MOD;
                        f[k][1]=((LL)f[k-1][0]*(a[k]%bin[i]+1)%MOD+(LL)f[k-1][1]*bin[i]%MOD)%MOD;
                    }
                    else f[k][0]=(LL)f[k-1][0]*(a[k]%bin[i]+1)%MOD,f[k][1]=(LL)f[k-1][1]*(a[k]%bin[i]+1)%MOD;
                if (m&bin[i]) (ans+=f[n][1])%=MOD;
                else (ans+=f[n][0])%=MOD;
            }
            int c=0;
            for (int j=1;j<=n;j++) c^=a[j]&bin[i];
            if (c!=(m&bin[i])) break;
        }
        int t=0;
        for (int i=1;i<=n;i++) t^=a[i];
        if (t==m) (ans+=1)%=MOD;
        printf("%d\n",ans);
        scanf("%d%d",&n,&m);
    }
    return 0;
}
阅读更多

The Diary of Math Teacher

11-02

Problem Descriptionn03/21/2010 SUN Sunnynn“Hi, boys and girls ,today we will learn the “Deference” .”n“What is the “Deference”? Is that difficult? ”n“Boys , don’t worry, and you will know it immediately.”nnn“f(x) is an function, and x is an integer. Δf( x ) = f (x + 1 ) – f( x ) ”n“In general, Δ(n+1)f( x ) = Δ(n)f( x+1 ) - Δ(n)f( x )”n“In particular, Δ(0)f( x ) = f( x ),Δ(1)f( x ) = Δf (x )”nnn“Do you understand?”n“No!!!!!!!!!!!!”n“Does anyone understand?”n“Only you our teacher!”n“How dare you be so ironic. Since you all have learnt the Factorial. I will give you a problem of factorial and difference. Anyone who can’t solve it will be severely punished”nnn“ The problem is:nGiven a nonnegative integer array a[n] , and each of its elements a[i] (1<=i<=n)is also known.nf(x)=∏1<=i<=n(x+a[i])nYour task is to calculate Δ(k)f(0)/k! ”nDamn it,really bad mood. Well, I'd better go to sleep now.n nnInputnMultiple test cases.nThe first line of each test case will be 3 integers : n(1<=n<=1000) , k(0<=k<=n-1) , p(1<=P<=20000).nThe following line will contain n integers a[i] (0<=a[i]<=20000).nInput ends with n=k=p=0.n nnOutputnFor each test case ,pint the answer mod p in one separate line.nThe last case n=k=p=0 does not need to be processed.n nnSample Inputn5 3 20000n1 0 0 1 0n5 3 7n1 0 1 0 0n3 1 7777n1 1 0n3 0 94n0 1 1n7 4 10000n0 1 0 3 0 1 0n16 12 17595n4898 287 4879 598 5927 8 764 57 233 188 58 97 899 9876 47 323n0 0 0n nnSample Outputn38n3n4n0n748n4035n

没有更多推荐了,返回首页