用的手写hash,1e6会挂两个点
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
#define ll long long
ll rest,x,y,nn,m,temp,ans,tot=-1;
const ll mo=3e6+7;
struct ed{
int v;
int next;
int first;
int d;
};
int k[7],p[7];
ed h[mo+7];
void qpower(ll i,ll p){
ll m=i;
rest=1;
while(p){
if(p&1)rest=rest*m;
m=m*m;
p=p>>1;
}
}
void dfs(ll n,ll cnt){
if(n==x){
int az=0;
temp=cnt%mo;
for(int i=1;i<=mo;i++){
if(temp>=0)break;
temp=temp+mo;
}
int k=h[temp].first;
while(k!=-1){if(h[k].v==cnt){h[k].d++;az=1;break;}k=h[k].next;}
if(az==0){
tot++;
h[tot].v=cnt;
h[tot].next=h[temp].first;
h[temp].first=tot;
h[tot].d=1;
}
return;
}
if(n<x)for(int i=1;i<=m;i++)
{qpower(i,p[n+1]);
cnt=cnt+rest*k[n+1];
dfs(n+1,cnt);
qpower(i,p[n+1]);
cnt=cnt-rest*k[n+1];
}
if(n==nn+1){
temp=cnt%mo;//wanyishi-
for(int i=1;i<=mo;i++){
if(temp>=0)break;
temp=temp+mo;
}
int k=h[temp].first;
while(k!=-1){
if(h[k].v==cnt){ans=ans+h[k].d;break;}
k=h[k].next;
}
return;
}
if(n>x)for(int i=1;i<=m;i++)
{qpower(i,p[n]);
cnt=cnt+rest*k[n];
dfs(n+1,cnt);
qpower(i,p[n]);
cnt=cnt-rest*k[n];
}
}
int main()
{
cin>>nn>>m;
for(int i=1;i<=nn;i++)
cin>>k[i]>>p[i];
x=nn/2;
for(int i=x+1;i<=nn;i++)k[i]=k[i]*-1;
for(int i=0;i<=mo;i++)h[i].first=-1;
int az;
dfs(0,0);
dfs(x+1,0);
cout<<ans;
return 0;
}