BestCoder Round #74 (div.2) T3 Transform HDOJ 5637

来源:互联网 发布:sql语言设计登陆验证码 编辑:程序博客网 时间:2024/05/22 03:09

/*
这道题有两种变化选择,一种翻转某一位很好办,对于另一种亦或操作:由于亦或有交换律,所以x^…^..=y也就等价于…^..=x^y,那就很好办,直接不停亦或就好啦O(∩_∩)O~
*/

 # include < iostream > # include < cstring > # include < cstdio >using namespace std;typedef long long ll;int dp[1<<17],a,T,n,m,si,ti;//1<<17大概就是13万多,对于这道题一万是足够的,dp[i]就代表已经亦或到i的时候的最小次数;ll ans,mod=1e9+7;int main(){        cin>>T;        while(T--)        {                ans=0;                for(int i=1;i<=(1<<17);i++)                {                        dp[i]=mod;                }//因为要求最小,先将数组设为一个大数;                dp[0]=0;//但是当j亦或它本身的时候会得到0,必须把dp[0]=0;                scanf("%d%d",&n,&m);                for (int i=1;i<=n;i++)                {                    scanf("%d",&a);//边输入便处理;                    for (int j=1;j<(1<<17);j++)                    {                            for (int k=0;k<17;k++)                            {                                     dp[j]=min(dp[j],dp[j^(1<<k)]+1);//这就是翻转其中的某一位;                            }                            dp[j]=min(dp[j],dp[j^a]+1);//这是亦或可选的数字;                    }                }                for(int i=1;i<=m;i++)                {                        scanf("%d%d",&si,&ti);                        ans=(ans+ll(i)*ll(dp[si^ti]))%mod;                }                printf("%I64d\n",ans);        }}

(膜拜szc大神)

0 0