wa了22次:HDU - 6501 B - Problem B. Memory Banks 取模1e9+7注意事项

http://acm.hdu.edu.cn/showproblem.php?pid=6501
Problem B. Memory Banks
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2807 Accepted Submission(s): 458

Problem Description
We have purchased 60 different types of memory banks, typed as 0 to 59, A bank of type i has 2^i memory capacity. We have Xi memory banks of type i.
We also have n workstations numbered from 1 to n. The ith workstation needs exactly (no more and no less) Wi memory capacity to work.
Each workstation can use unlimited amount of memory banks, Total memory capacity of this workstation is the sum of capacity of all memory banks it used.
We need to make all workstations work and calculate the total capacity of unused memory banks, can you help us?

Input
Input is given from Standard Input in the following format:
X0 … X59
n
W1 … Wn
Constraints
0 ≤ Xi ≤ 2^60
1 ≤ n ≤ 100000
0 ≤ Wi ≤ 2^60
All of them are integers.

Output
Print one line denotes the answer.
If it is possible to make all workstations work, output a single number represents the total capacity of unused memory banks. It maybe very large, you should modulo 1000000007(10^9 + 7)
Otherwise output -1

Sample Input
4 2 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
3
10 8 16
2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0
4
2 4 8 1

Sample Output
6
-1

Source
2018 东北地区大学生程序设计竞赛

Recommend
We have carefully selected several similar problems for you: 6900 6899 6898 6897 6896

思路:每个station用使用若干个bank,The ith workstation needs exactly (no more and no less) Wi memory capacity to work. 意味着必须找到用若干个bank恰好填充每个station的方式,若找不到则返回-1,找到则返回剩余容量。
注意:取模运算时,每一个需要取模的变量都要重新设变量储存取模结果,之后再用新变量进行运算,有以下两个原因。
1.A%mod*B%mod有可能A%mod和B相乘的结果爆long long
2.如果之后样例要用到A,一定不能写成A%=mod; 改变了A的值会影响后续运算。

#include <bits/stdc++.h>

using namespace std;
unsigned long long a[100];
const unsigned long long mod=1000000007;
void init()
{
    a[0]=1;
    for(int i=1;i<=61;i++)
    {
        a[i]=a[i-1]*2;
    }
}
int main()
{

    //cout << "Hello world!" << endl;
    init();
    unsigned long long X[100];
    while(cin>>X[0])
    {
        for(int i=1;i<=59;i++)
        {
            cin>>X[i];
        }
        long long n;
        cin>>n;
        long long b[100000+1000];
        for(int i=0;i<n;i++)
        {
            cin>>b[i];
        }
        sort(b,b+n);
        int flag=0;
        for(int i=n-1;i>=0;i--)
        {
            for(int j=59;j>=0;j--)
            {
                /*while(b[i]>=a[j]&&X[j]>0)
                {
                    b[i]-=a[j];
                    X[j]--;
                }*/
                long long t=b[i]/a[j];//b是station, a是库存
                if(X[j]==0)continue;
                if(t>X[j])
                {
                    b[i]-=a[j]*X[j];
                    X[j]=0;
                }
                else if(t<=X[j])
                {
                    X[j]-=t;
                    b[i]-=t*a[j];
                }
            }
            if(b[i]!=0)flag=1;
        }
        if(flag==1)
        {
            cout<<"-1"<<endl;
            continue;
        }
        else
        {
            unsigned long long ans=0;
            for(int i=0;i<60;i++)
            {
                long long u=a[i]%mod,v=X[i]%mod;//这个点,害我们wa22次
                ans+=u*v;
                ans%=mod;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值