CCPC 威海 Lottery

CCPC 威海 Lottery

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+7;
/*
7-12 Lottery题解:
思路很简单,其实就是找连续的一段数,那么说明这个连续的区间都可以生成
然后相乘,就是最后的答案
这个题目的x和a都很大,这个怎么判断呢
对于 x1*2^a1 和 x2*2^a2 ,如果x1>2^(a2-a1),那么说明可以连起来,然后把对于2^a2次方的贡献加上去即可
因为 x<1e9 所以 a2-a1<31
*/
struct node{
    ll a,x,base;
    node(ll a=0,ll x=0,ll base = 0):a(a),x(x),base(base){}
}e[maxn];
ll f[100];
void init(){
    f[0] = 1;
    for(int i=1;i<=40;i++) f[i] = f[i-1]*2;
}
bool cmp(node A,node B){
    return A.a<B.a;
}
long long binpow(long long x,long long k) {
    x %= mod;
    long long ans = 1;
    while (k) {
        if (k & 1) ans = ans * x % mod;
        x = x * x % mod;
        k >>= 1;
    }
    return ans;
}
int main(){
    int T;
    init();
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            int a,x;
            scanf("%d%d",&a,&x);
            e[i] = node(a,x,x);
        }
        sort(e+1,e+1+n,cmp);
        ll ans = 1,pre = e[1].a,sum = 0;
        for(int i=1;i<=n;i++){
            sum = (sum + binpow(2,e[i].a-pre)*e[i].base%mod)%mod;
            if(i<n&&e[i+1].a - e[i].a<=30&&(e[i].x>>(e[i+1].a-e[i].a))){
                e[i+1].x += e[i].x>>(e[i+1].a-e[i].a);
            }
            else{
                ans = ans*(sum+1)%mod;
                sum = 0,pre = e[i+1].a;
            }

        }
        printf("Case #%d: %lld\n", cas,ans);
    }
    return 0;
}
posted @ 2020-11-06 08:27  EchoZQN  阅读(166)  评论(0编辑  收藏  举报