hdu
[l,r]做n次异或相当于把[l,r]分成
log段,做矩阵快速幂
#include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; const ll mod=1000000007; ll powmod(ll a,ll b) { ll res=1; a%=mod; assert(b>=0); for(; b; b>>=1) { if(b&1)res=res*a%mod; a=a*a%mod; } return res; } ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } // head int _,n,l,r,Q,x; struct segment { int pl,len; ll v; }; vector<segment> seg,ret; void query(int len,int l,int r,int tl,int tr) { if (l==tl&&r==tr) { seg.pb((segment) { tl,len,1 }); } else { int md=(l+r)>>1; if (tr<=md) query(len-1,l,md,tl,tr); else if (tl>md) query(len-1,md+1,r,tl,tr); else query(len-1,l,md,tl,md),query(len-1,md+1,r,md+1,tr); } } struct Hash_table { static const int V=1000003; int fst[V],nxt[V]; int ctm,ptm[V],T; ll val[V]; ll key[V]; void init() { T=0; ctm++; } void add(ll s,int v) { int S=s%V; if (ptm[S]!=ctm) ptm[S]=ctm,fst[S]=-1; for (int j=fst[S]; j!=-1; j=nxt[j]) if (key[j]==s) { val[j]+=v; return; } nxt[T]=fst[S],fst[S]=T,key[T]=s,val[T]=v; T++; } } hs; vector<segment> mul(vector<segment> &a,vector<segment> &b) { hs.init(); for (auto p:a) for (auto q:b) { int fred=max(p.len,q.len); int c=min(p.len,q.len); int tl=((p.pl^q.pl)>>fred)<<fred; ll tot=p.v*q.v%mod*(1ll<<c)%mod; hs.add(tl*100ll+fred,tot); } vector<segment> c; rep(i,0,hs.T) { pair<ll,ll> p(hs.key[i],hs.val[i]); c.pb((segment) { (int)(p.fi/100),(int)(p.fi%100),p.se%mod }); } return c; } int main() { for (scanf("%d",&_); _; _--) { scanf("%d%d%d%d",&n,&l,&r,&Q); seg.clear(); ret.clear(); query(30,0,(1<<30)-1,l,r); // debug(seg); ret.pb((segment) { 0,0,1 }); for (; n; n>>=1) { if (n&1) ret=mul(ret,seg); seg=mul(seg,seg); // printf("%d %d\n",SZ(seg),SZ(ret)); } rep(i,0,Q) { scanf("%d",&x); int ans=0; for (auto p:ret) { if (p.pl<=x&&x<p.pl+(1<<p.len)) ans=(ans+p.v)%mod; } printf("%d\n",ans); } } }