The Preliminary Contest for ICPC Asia Nanjing 2019
A. The beautiful values of the palace(树状数组+二维前缀和)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define isZero(d) (fabs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=1e9+7;
int t,n,m,q;
int ans[maxn];
ll C[maxn*10];
struct Node
{
int x,y,id,val,f;
bool operator<(const Node & b) const
{
if(x!=b.x)
return x<b.x;
if(y!=b.y)
return y<b.y;
return id<b.id;
}
}p[maxn*5];
int lowbit(int x)
{
return x&(-x);
}
void add(int pos,int val)
{
for(int i=pos;i<=n;i+=lowbit(i))
C[i]+=val;
}
ll getsum(int pos)
{
int ret=0;
for(int i=pos;i>0;i-=lowbit(i))
ret+=C[i];
return ret;
}
int getval(int x,int y)
{
int t=min(min(x,y),min(n-x+1,n-y+1));
int len=n-t*2+2;
ll val=1ll*n*n-1ll*len*len;
if(x==t)
val+=2*len-1+y-t;
else if(x==n-t+1)
val+=n-y+1-(t-1);
else if(y==t)
val+=len+n-x+1-t;
else if(y==n-t+1)
val+=3*len-2+x-t;
int ans=0;
while(val)
{
ans+=val%10;
val/=10;
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=q;++i)
ans[i]=0;
for(int i=1;i<=n;++i)
C[i]=0;
for(int i=1;i<=m;++i)
{
int x,y;
scanf("%d%d",&x,&y);
int val=getval(x,y);
p[i]={x,y,i,val,0};
}
int cnt=m;
for(int i=m+1;i<=m+q;++i)
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
p[++cnt]={x1-1,y1-1,i,0,1};
p[++cnt]={x1-1,y2,i,0,-1};
p[++cnt]={x2,y1-1,i,0,-1};
p[++cnt]={x2,y2,i,0,1};
}
sort(p+1,p+1+cnt);
for(int i=1;i<=cnt;++i)
{
if(p[i].id<=m)
add(p[i].y,p[i].val);
else
ans[p[i].id-m]+=getsum(p[i].y)*p[i].f;
}
for(int i=1;i<=q;++i)
printf("%d\n",ans[i]);
}
return 0;
}
B. super_log(欧拉降幂)
题意:求解
a
a
…
a
a^{a^{\dots^a}}
aa…a % m的值
思路:m等于1的时候,返回
x
%
m
+
m
x\%m+m
x%m+m,即返回1。递归出口返回1还是0,取决于后面的操作,如果后面还有判断的操作,就返回x%m,否则就返回x%m+m
#include <iostream>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;
int t;
ll a,b,m;
ll mm(ll x,ll m)
{
return x<m?x:x%m+m;
}
ll qpow(ll base,ll n,ll mod)
{
ll ret=1;
while(n)
{
if(n&1)
ret=mm(ret*base,mod);
base=mm(base*base,mod);
n>>=1;
}
return ret;
}
ll phi(ll n)
{
ll a=n,ans=n;
for(ll i=2;i*i<=a;++i)
{
if(a%i==0)
{
ans=ans/i*(i-1);
while(a%i==0)
a/=i;
}
}
if(a>1)
ans=ans/a*(a-1);
return ans;
}
ll solve(ll a,ll b,ll m)
{
if(m==1)
return 1;
if(b==0)
return 1;
ll x=solve(a,b-1,phi(m));
return qpow(a,x,m);
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&a,&b,&m);
printf("%lld\n",solve(a,b,m)%m);
}
return 0;
}
C. Tsy’s number 5(NTT)
题意:给出n,求
∑
i
=
1
n
∑
j
=
1
n
φ
(
i
)
φ
(
j
)
2
φ
(
i
)
φ
(
j
)
\sum_{i=1}^n\sum_{j=1}^n \varphi(i)\varphi(j)2^{\varphi(i)\varphi(j)}
∑i=1n∑j=1nφ(i)φ(j)2φ(i)φ(j)模998244353的值
思路:设
f
(
i
)
=
∑
k
=
1
n
[
φ
(
k
)
=
i
]
f(i)=\sum_{k=1}^n[\varphi(k)=i]
f(i)=∑k=1n[φ(k)=i]
原式化简为:
核心思想就是:把多个
i
i
i 相等的
φ
(
i
)
\varphi(i)
φ(i),合并在一起统计,枚举到i这个数的时候,就把它当做欧拉函数的值。
f
(
i
)
f(i)
f(i)就是这个函数值在
[
1
,
n
]
[1,n]
[1,n]出现的次数
∑
i
=
1
n
∑
j
=
1
n
f
(
i
)
f
(
j
)
i
j
2
i
j
\sum_{i=1}^n\sum_{j=1}^n f(i)f(j)ij2^{ij}
i=1∑nj=1∑nf(i)f(j)ij2ij
又有 2 i j = 2 ( i + j ) 2 − i 2 − j 2 2 = 2 ( i + j ) 2 − i 2 − j 2 2^{ij}=2^{\frac {(i+j)^2-i^2-j^2}2}=\sqrt2 ^{(i+j)^2-i^2-j^2} 2ij=22(i+j)2−i2−j2=2(i+j)2−i2−j2
因此所求就是
∑ i = 1 n f ( i ) i 2 − i 2 ∑ j = 1 n f ( j ) j 2 − j 2 2 ( i + j ) 2 \sum_{i=1}^nf(i)i\sqrt2 ^{-i^2}\sum_{j=1}^nf(j)j\sqrt2^{-j^2}\sqrt2^{(i+j)^2} i=1∑nf(i)i2−i2j=1∑nf(j)j2−j22(i+j)2
然后NTT右边的式子,就可以了
贴一份题解的推导
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define isZero(d) (fabs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=998244353,sqrt2=116195171;
ll qpow(ll base,ll n,ll mod)
{
ll ret=1;
while(n)
{
if(n&1)
ret=ret*base%mod;
n>>=1;
base=base*base%mod;
}
return ret;
}
const int G=3,P=998244353,GI=332748118;
struct NTT
{
int total,digit,rev[maxn*6];
ll a[maxn*6],b[maxn*6];
void init(int len)
{
total=1,digit=0;
while(total<=len)
total<<=1,digit++;
for(int i=0;i<total;++i)
{
rev[i]=(rev[i>>1]>>1)|(i&1)<<(digit-1);
a[i]=0,b[i]=0;
}
}
void ntt(ll *A,int f)
{
for(int i=0;i<total;++i)
if(i<rev[i])
swap(A[i],A[rev[i]]);
for(int mid=1;mid<total;mid<<=1)
{
ll Wn,len=mid*2;;
if(f==1)
Wn=qpow(G,(P-1)/len,P);
else
Wn=qpow(GI,(P-1)/len,P);
for(int p=0;p<total;p+=len)
{
ll Wk=1;
for(int k=0;k<mid;++k)
{
int x=A[p+k],y=Wk*A[p+k+mid]%P;
A[p+k]=(x+y)%P;
A[p+k+mid]=(x-y+P)%P;
Wk=Wk*Wn%P;
}
}
}
if(f==-1)
{
ll inv=qpow(total,P-2,P);
for(int i=0;i<total;++i)
a[i]=a[i]*inv%P;
}
}
void calc()
{
ntt(a,1),ntt(b,1);
for(int i=0;i<total;++i)
a[i]=a[i]*b[i]%P;
ntt(a,-1);
}
}ntt;
const int N=1e5+10;
int visit[N+10],prime[N+10],cnt;
int phi[N+10];
void init()
{
cnt=0,phi[1]=1;
for(int i=2;i<=N;++i)
{
if(!visit[i])
prime[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt&&i*prime[j]<=N;++j)
{
visit[i*prime[j]]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
int n,t;
ll f[maxn],a[maxn];
int main()
{
init();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ntt.init(3*n);
for(int i=0;i<=n;++i)
f[i]=0;
for(int i=1;i<=n;++i)
f[phi[i]]++;
for(int i=1;i<=n;++i)
a[i]=ntt.a[i]=1ll*f[i]*i%mod*qpow(sqrt2,-1ll*i*i%(mod-1)+mod-1,mod)%mod;
for(int i=1;i<=2*n;++i)
ntt.b[i]=qpow(sqrt2,1ll*i*i%(mod-1),mod);
reverse(ntt.a+1,ntt.a+1+n);
ntt.calc();
ll ans=0;
for(int i=1;i<=n;++i)
ans=(ans+1ll*a[i]*ntt.a[n+i+1])%mod;
printf("%lld\n",ans);
}
return 0;
}
D. Robots
E. K Sum(推式子+积性函数线性筛+等比数列求和+欧拉降幂)
题意:定义 f n ( k ) = ∑ l 1 n ∑ l 2 n ⋯ ∑ l k n g c d ( l 1 , l 2 , … , l k ) 2 f_n(k)=\sum_{l_1}^n\sum_{l_2}^n\dots\sum_{l_k}^n gcd(l_1,l_2,\dots,l_k)^2 fn(k)=∑l1n∑l2n⋯∑lkngcd(l1,l2,…,lk)2,给定n,k,求 ∑ i = 2 k f n ( i ) \sum_{i=2}^k f_n(i) ∑i=2kfn(i),对1e9+7取模
思路:推式子+杜教筛+等比数列求和
推导过程挺简单的,关键是后面的处理。
最终推得的式子为:
∑
T
=
1
n
∑
d
∣
T
μ
(
d
)
(
T
d
)
2
∑
i
=
2
k
⌊
n
T
⌋
i
\sum_{T=1}^n\sum_{d|T}\mu(d)(\frac Td)^2 \sum_{i=2}^k\lfloor \frac nT\rfloor ^i
T=1∑nd∣T∑μ(d)(dT)2i=2∑k⌊Tn⌋i
设
f
(
T
)
=
∑
d
∣
T
μ
(
d
)
(
T
d
)
2
f(T)=\sum_{d|T}\mu(d)(\frac Td)^2
f(T)=∑d∣Tμ(d)(dT)2,因此就是求左边一个积性函数前缀和,右边一个等比数列前缀和
1、积性函数前缀和,用杜教筛,首先对积性函数做线性筛
f
(
1
)
=
1
f(1)=1
f(1)=1
f
(
p
)
=
p
2
−
1
f(p)=p^2-1
f(p)=p2−1
f
(
p
k
)
=
p
2
k
−
p
2
k
−
2
f(p^k)=p^{2k}-p^{2k-2}
f(pk)=p2k−p2k−2
f
(
p
k
+
1
)
=
p
2
k
+
2
−
p
2
k
f(p^{k+1})=p^{2k+2}-p^{2k}
f(pk+1)=p2k+2−p2k
2、然后观察f(T)的卷积,
f
(
T
)
=
μ
∗
(
i
d
)
2
f(T)=\mu*(id)^2
f(T)=μ∗(id)2
我们要凑一个h,
h
=
f
∗
g
=
u
∗
(
i
d
)
2
∗
g
h=f*g=u*(id)^2*g
h=f∗g=u∗(id)2∗g,这时我们知道
μ
∗
I
=
ϵ
\mu*I=\epsilon
μ∗I=ϵ,因此我们卷上
I
I
I,即
h
=
i
d
2
h=id^2
h=id2
这样就可以将g、h带入公式了
S
(
n
)
=
∑
i
=
1
n
i
2
−
∑
d
=
2
n
S
(
⌊
n
d
⌋
)
S(n)=\sum_{i=1}^ni^2-\sum_{d=2}^nS(\lfloor \frac nd\rfloor)
S(n)=i=1∑ni2−d=2∑nS(⌊dn⌋)
3、我们再处理右边的等比数列,设 q = ⌊ n T ⌋ q=\lfloor \frac nT \rfloor q=⌊Tn⌋
- 当q=1时,即k-1,k很大直接对mod取模
- 当q不为1时,即
q
2
+
q
3
+
⋯
+
q
k
q^2+q^3+\dots+q^k
q2+q3+⋯+qk,求和后化简,即:
q k + 1 − q 2 q 2 − 1 \frac {q^{k+1}-q^2}{q^2-1} q2−1qk+1−q2
k很大,又在指数的位置,所以这个k需要对 m o d − 1 mod-1 mod−1取模
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define isZero(d) (fabs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=1e9+7;
int inv6;
int qpow(int base,int n,int mod)
{
int ret=1;
while(n)
{
if(n&1)
ret=1ll*ret*base%mod;
base=1ll*base*base%mod;
n>>=1;
}
return ret;
}
const int N=1e6;
int prime[N+10],visit[N+10],cnt;
ll f[N+10],low[N+10];
void init()
{
cnt=0,f[1]=1;
for(int i=2;i<=N;++i)
{
if(!visit[i])
prime[++cnt]=i,f[i]=(1ll*i*i-1)%mod,low[i]=i;
for(int j=1;j<=cnt&&i*prime[j]<=N;++j)
{
visit[i*prime[j]]=1;
if(i%prime[j]==0)
{
low[i*prime[j]]=low[i]*prime[j];
if(low[i]==i)
f[i*prime[j]]=f[i]*prime[j]%mod*prime[j]%mod;
else
f[i*prime[j]]=f[i/low[i]]*f[low[i]*prime[j]];
break;
}
low[i*prime[j]]=prime[j];
f[i*prime[j]]=f[i]*f[prime[j]];
}
}
for(int i=1;i<=N;++i)
f[i]=(f[i]+f[i-1])%mod;
}
int abss(int x)
{
if(x<0)
x+=mod;
return x;
}
unordered_map<int,int> mf;
int S(int n)
{
if(n<=N)
return f[n];
if(mf[n])
return mf[n];
int ans=1ll*n*(n+1)%mod*(2*n+1)%mod*inv6%mod,l=2,r;
while(l<=n)
{
r=n/(n/l);
ans=(ans-1ll*(r-l+1)*S(n/l)%mod+mod)%mod;
l=r+1;
}
return mf[n]=ans;
}
int G(int q,int k1,int k2)
{
if(q==1)
return (k1-1+mod)%mod;
int ans=abss(1ll*qpow(q,k2+1,mod)-1ll*q*q%mod);
return 1ll*ans*qpow(q-1,mod-2,mod)%mod;
}
int t,n;
string k;
int main()
{
inv6=qpow(6,mod-2,mod);
init();
cin>>t;
while(t--)
{
cin>>n>>k;
int k1=0,k2=0;
for(auto i : k)
{
k1=(1ll*k1*10+i-'0')%mod;
k2=(1ll*k2*10+i-'0')%(mod-1);
}
int l=1,r,ans=0;
while(l<=n)
{
r=n/(n/l);
ans=(1ll*ans+1ll*abss(S(r)-S(l-1))*G(n/l,k1,k2)%mod)%mod;
l=r+1;
}
printf("%d\n",ans);
}
return 0;
}
F. Greedy Sequence(主席树||线段树||滑动窗口)
解法一:主席树
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define isZero(d) (fabs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=1e9+7;
int t,n,k;
int a[maxn],pos[maxn],ans[maxn];
int root[maxn],ST[maxn*40],ls[maxn*40],rs[maxn*40],no;
int Build(int L,int R)
{
int rt=++no;
ST[rt]=0;
if(L==R)
return rt;
int mid=(L+R)>>1;
ls[rt]=Build(L,mid);
rs[rt]=Build(mid+1,R);
return rt;
}
int Update(int pre,int p,int L,int R)
{
int rt=++no;
ls[rt]=ls[pre];
rs[rt]=rs[pre];
ST[rt]=ST[pre]+1;
if(L==R)
return rt;
int mid=(L+R)>>1;
if(p<=mid)
ls[rt]=Update(ls[pre],p,L,mid);
if(p>mid)
rs[rt]=Update(rs[pre],p,mid+1,R);
return rt;
}
int Query(int pre,int now,int p,int L,int R)
{
if(ST[now]-ST[pre]==0)
return -1;
if(L==R)
return L<p?L:-1;
int mid=(L+R)>>1;
int x=-1;
if(p>mid+1)
x=Query(rs[pre],rs[now],p,mid+1,R);
if(x!=-1)
return x;
return Query(ls[pre],ls[now],p,L,mid);
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
pos[a[i]]=i;
ans[i]=0;
}
no=0;
root[0]=Build(1,n);
for(int i=1;i<=n;++i)
root[i]=Update(root[i-1],a[i],1,n);
for(int i=1;i<=n;++i)
{
int l=max(pos[i]-k,1);
int r=min(pos[i]+k,n);
int x=Query(root[l-1],root[r],i,1,n);
ans[i]=ans[x]+1;
}
for(int i=1;i<=n;++i)
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}
解法二:线段树
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define isZero(d) (fabs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=1e9+7;
int t,n,k;
int a[maxn],pos[maxn],ST[maxn<<2];
int ans[maxn];
void Push_up(int rt)
{
ST[rt]=max(ST[ls],ST[rs]);
}
void Build(int rt,int L,int R)
{
ST[rt]=0;
if(L==R)
return;
int mid=(L+R)>>1;
Build(ls,L,mid);
Build(rs,mid+1,R);
}
void Update(int rt,int p,int L,int R,int val)
{
if(L==R)
{
ST[rt]=val;
return;
}
int mid=(L+R)>>1;
if(p<=mid)
Update(ls,p,L,mid,val);
if(p>mid)
Update(rs,p,mid+1,R,val);
Push_up(rt);
}
int Query(int rt,int l,int r,int L,int R)
{
if(l<=L&&R<=r)
return ST[rt];
int maxx=0;
int mid=(L+R)>>1;
if(l<=mid)
maxx=max(maxx,Query(ls,l,r,L,mid));
if(r>mid)
maxx=max(maxx,Query(rs,l,r,mid+1,R));
return maxx;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]),pos[a[i]]=i;
Build(1,1,n);
for(int i=1;i<=n;++i)
{
int l=max(pos[i]-k,1);
int r=min(pos[i]+k,n);
int x=Query(1,l,r,1,n);
ans[i]=ans[x]+1;
Update(1,pos[i],1,n,i);
}
for(int i=1;i<=n;++i)
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}
解法三:滑动窗口
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define isZero(d) (abs(d) < 1e-8)
using namespace std;
const int maxn=1e5+5,INF=0x3f3f3f3f;
const int mod=1e9+7;
int t,n,k,a[maxn],pos[maxn],l[maxn],r[maxn];
int ans[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&k);
rep(i,1,n)
{
scanf("%d",&a[i]);
l[i]=r[i]=0;
pos[a[i]]=i;
}
set<int> s;
for(int i=1;i<=n;++i)
{
s.insert(a[i]);
if(i-k-1>=1)
s.erase(a[i-k-1]);
auto it=s.lower_bound(a[i]);
if(it!=s.begin())
l[a[i]]=*(--it);
}
s.clear();
for(int i=n;i>=1;--i)
{
s.insert(a[i]);
if(i+k+1<=n)
s.erase(a[i+k+1]);
auto it=s.lower_bound(a[i]);
if(it!=s.begin())
r[a[i]]=*(--it);
}
for(int i=1;i<=n;++i)
{
int x=max(l[i],r[i]);
ans[i]=ans[x]+1;
printf("%d%c",ans[i],i==n?'\n':' ');
}
}
return 0;
}
G. Quadrilateral(容斥)
#include <iostream>
#include <algorithm>
#include <cstdio>
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define ll long long
using namespace std;
int T,x[10];
ll f(ll n)
{
return (1+n)*n/2;
}
ll f2(ll n)
{
return n*(n+1)*(n+2)/6;
}
ll cal(ll a,ll b,ll c)
{
if(a<1||b<1||c<2)
return 0;
a=min(a,c-1);
b=min(b,c-1);
if(a+b<=c)
return (f(c-1)-f(c-b-1)+f(c-a)-f(c-a-b))*a/2;
else
return (f(c-1)-f(c-b-1)+f(b))*(c-b)/2+f2(b-1)-f2(c-a-1);
}
ll solve(ll a,ll b,ll c,ll d)
{
if(a<1||b<1||c<1||d<1)
return 0;
ll ret=1ll*a*b*c;
ret-=cal(b,c,d-1)-cal(b,c,d-a-1);
ret-=cal(a,b,c-d);
ret-=cal(a,c,b-d);
ret-=cal(b,c,a-d);
return ret;
}
int main()
{
scanf("%d",&T);
while(T--)
{
rep(i,1,8)
scanf("%d",&x[i]);
ll ans=0;
for(int i=x[7];i<=x[8];++i)
{
ans+=solve(x[2],x[4],x[6],i)-solve(x[1]-1,x[4],x[6],i)-solve(x[2],x[3]-1,x[6],i)
-solve(x[2],x[4],x[5]-1,i)+solve(x[1]-1,x[3]-1,x[6],i)+solve(x[1]-1,x[4],x[5]-1,i)
+solve(x[2],x[3]-1,x[5]-1,i)-solve(x[1]-1,x[3]-1,x[5]-1,i);
}
printf("%lld\n",ans);
}
return 0;
}