UVA 10542 Hyper-drive (容斥定理+規律)*
阿新 • • 發佈:2018-12-17
#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #define ll long long #define lrt int l,int r,int rt #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define root l,r,rt const int maxn =5e2+5; const int mod=1e9+7; const int ub=10000; ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;} ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} int gcd(int x,int y){return y?gcd(y,x%y):x;} /* 題目大意:給定k維的物體, 求兩端點之間直線經過的k維物體數量。 通過二維類比推出k維, 首先考慮二維的情況, 不難看出方塊數是a+b-1, 然後考慮消去重複度, gcd(a,b)就是直線經過的方格點個數, 但要去掉(a,b)本身, 式子一總結就是:sigma gcd({xi})* (|{xi}|為奇?1:-1) 其中{xi}就是維度點的子集。 這道題還是蠻抽象的。。。 因為在k維體裡直線經過的方塊點肯定是某個維度上的gcd, 所以考慮列舉子集進行容斥。 */ int a[15],b[15]; int n; int main() { int t; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) { scanf("%d",&b[i]); b[i]=abs(b[i]-a[i]); } ll ans=0; for(int i=0;i<(1<<n);i++) { int xishu=-1,ret=0; for(int j=0;j<n;j++) { if(i&(1<<j)) { xishu*=-1; ret=gcd(ret,b[j]); } } ///cout<<ret<<endl; ans+=1LL*ret*xishu; } printf("Case %d: %lld\n",ca,ans); } return 0; }