- 一定要注意取模啊!这道题当时不取模调试了2hour炸了啊!
思路
- 思维题:先将所有
a
i
a_i
ai排序,考察相邻的幂次差距。将第一个
a
i
a_i
ai往后转移一个,考虑子问题即可。两种情况:
- 小于等于余数的个数乘以后面子问题的所有方案
- 大于余数的只能乘后面子问题的所有方案减去1
#include <bits/stdc++.h>
using namespace std;
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<algorithm>
#include<map>
#include<queue>
#include <chrono>
#include<math.h>
#include<unordered_map>
using namespace std;
const int N = 1e5+5;
const int S = 500;
const long long mod = 1e9+7;
typedef long long ll;
void solve(pair<ll,ll> a[],int n,int i)
{
ll temp[n][2];
for(int i = 0;i<n;i++) temp[i][0]=temp[i][1]=a[i].second;
for(int i = 1;i<n;i++)
{
if(a[i].first - a[i-1].first >= 60)
{
continue;
}
else
{
ll d_1 = temp[i-1][0]/((ll)1 << (a[i].first - a[i-1].first));
ll d_2 = temp[i-1][1]/((ll)1 << (a[i].first - a[i-1].first));
if(d_1 > d_2)
{
temp[i][0]+=d_1; temp[i][1]+=d_2;
}
else
{
if(d_1 == 0) continue;
temp[i][0]+=d_1;
temp[i][1]+=(d_1-1);
}
}
}
ll ans[n][2];
ans[n-1][0]=temp[n-1][0]+1;
ans[n-1][1]=temp[n-1][1]+1;
for(int i = n-2;i>=0;i--)
{
if(a[i+1].first - a[i].first >= 60)
{
ans[i][0]=((temp[i][0]+1)%mod * (ans[i+1][0])%mod)%mod;
ans[i][1]=((temp[i][1]+1)%mod * (ans[i+1][1])%mod)%mod;
}
else
{
ll d_1 = temp[i][0]/((ll)1 << (a[i+1].first - a[i].first));
ll d_2 = temp[i][1]/((ll)1 << (a[i+1].first - a[i].first));
ll r_1 = temp[i][0]%((ll)1 << (a[i+1].first - a[i].first));
ll r_2 = temp[i][1]%((ll)1 << (a[i+1].first - a[i].first));
if(d_1>d_2)
{
ans[i][0]=((ans[i+1][0])%mod + ((r_2)%mod * (ans[i+1][1])%mod)%mod)%mod;
ans[i][1]=((r_2+1)%mod * (ans[i+1][1])%mod)%mod;
}
else
{
ll div = (ll)1 << (a[i+1].first - a[i].first);
ans[i][0] = (((r_1+1)%mod * (ans[i+1][0] % mod)) % mod);
ans[i][1] = (((r_2+1)%mod * (ans[i+1][0] % mod)) % mod);
if(d_1 != 0)
{
ans[i][0]+=((div-r_1-1)%mod * (ans[i+1][1]%mod))%mod;
ans[i][1]+=((div-r_2-1)%mod * (ans[i+1][1]%mod))%mod;
}
}
}
}
printf("Case #%d: %lld\n",i,ans[0][0]%mod);
}
int main()
{
int T;
cin >> T;
for(int i = 0;i<T;i++)
{
int n;
cin >> n;
pair<ll,ll> x[n];
for(int j = 0;j<n;j++)
{
cin >> x[j].first; cin >> x[j].second;
}
sort(x,x+n);
solve(x,n,i+1);
}
return 0;
}