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
", cas,ans);
}
return 0;
}