题目:是给你n个ai,一个xi,代表有xi个2^ai,然后问你拿这些最多可以组成多少个不同的数.xi和ai的范围都是1e9级别的,n是1e5级别的.
首先对于每个ai和xi来说,我们考虑它能延申到的长度.假如没有交集很显然就是直接乘起来就好了.假如有交集也挺显然的,就是拿前面能扩展到这里的最低位ai,拿2^(aj-ai)*xj即可,一个一个考虑计数就不会出现重复的现象.然后这题就没了.
代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e5+5;
struct JS{
    ll a,x,y;
}w[N<<2];

ll qp(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }return res;
}

bool cmp(JS l,JS r)
{
    if(l.a==r.a)    return l.x<r.x;
    else            return l.a<r.a;
}

int main()
{
    int T,g=0;
    scanf("%d",&T);
    while(T--)
    {
        ll n;
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&w[i].a,&w[i].x);
            w[i].y=w[i].x;
        }sort(w+1,w+1+n,cmp);
        ll ans=1;
        for(int i=1;i<=n;)
        {
            int r=i;
            while(w[r+1].a-w[r].a<33&&r<n)
            {
                if((w[r].x)>>(w[r+1].a-w[r].a)==0)    break;
                w[r+1].x+=(w[r].x)>>(w[r+1].a-w[r].a);
                r++;
            }
            for(int j=i+1;j<=r;j++)
            {
                w[i].y=(w[i].y+qp(2,w[j].a-w[i].a)*w[j].y)%mod;
            }ans=ans*(w[i].y+1);
            i=r+1;
        }
        printf("Case #%d: %lld\n",++g,ans);
    }
    return 0;
}