第一题
具体思路:状压DP
f[i][j]表示最后一个点是i,选了j这些点的方案数
AC代码
#pragma GCC optimize(3) #pragma GCC target("avx") #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-fhoist-adjacent-loads") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") #include<bits/stdc++.h> using namespace std; int n,i,j,x[100],y[100],must[100][100],k; int dp[21][1010000],ha=100000007;; double dis(int a,int b) { return sqrt((double)(x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } bool on(int a,int b,int c) { if(fabs(dis(a,b)+dis(a,c)-dis(b,c))<1e-6)return 1;else return 0; } int main() { scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]); for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j) { int now=0; for(k=1;k<=n;k++) if(on(k,i,j)) { now|=(1<<(k-1)); } must[i][j]=now; } for(i=1;i<=n;i++)dp[i][1<<(i-1)]=1; for(j=0;j<=(1<<n)-1;j++) for(i=1;i<=n;i++) if(j&(1<<(i-1))) { for(k=1;k<=n;k++) if((j&(1<<(k-1)))==0) { int now=j|(1<<(k-1)); if(must[i][k]==(must[i][k]&now)) { dp[k][now]=(dp[k][now]+dp[i][j])%ha; } } } int ans=0; for(i=1;i<=n;i++) for(j=0;j<=(1<<n)-1;j++) if((1<<(i-1)&j)) { int tot=0; for(k=1;k<=n;k++) if((1<<(k-1)&j))tot++; if(tot>=4)ans=(ans+dp[i][j])%ha; } printf("%d",ans); return 0; }
第二题
具体思路:ans=(2^(n+1))/3
加个高精度就好了
AC代码
#include<bits/stdc++.h> #define LL long long const LL MAX_LEN=50004; const LL base=1e8; const int baselen=8; using namespace std; int n,i,j; namespace BigNumber{ const int L=10010,Base=10000,Bit=4; const LL MaxInt=2147483647; const int Pw10[15]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000}; const int Pw2[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536}; LL DOF[L]; struct BigNum{ int v[L],le,flag; BigNum(){ memset(v,0,sizeof v); le=flag=1; } BigNum(int x){ flag=1; le=1; memset(v,0,sizeof v); if (x<0) flag=-1,x=-x; v[1]=x; while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le; } BigNum(LL x){ flag=1; le=1; memset(v,0,sizeof v); if (x<0) flag=-1,x=-x; v[1]=x%Base; v[2]=x/Base%Base; v[3]=x/Base/Base%Base; v[4]=x/Base/Base/Base; le=4; while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le; while (v[le]==0 && le>1) --le; } BigNum(int len,int fir){ memset(v,0,sizeof v); le=len; v[le]=fir; flag=1; } BigNum(const BigNum &a,int x){ memset(v,0,sizeof v); le=a.le+x; flag=a.flag; for (int i=1;i<=a.le;++i) v[i+x]=a.v[i]; } int IntoInt(){ if (le>3) cerr <<"error: cannot change so big into int!"<<endl; LL d=0; for (int i=le;i>=1;--i) d=d*Base+v[i]; if (flag==-1) d=-d; if (d>MaxInt || -d<MaxInt+1) cerr <<"error: cannot change so big into int!"<<endl; return d; } void Clear(){ memset(v,0,sizeof v); le=flag=1; } void operator =(int a){ if (a < 0) flag=-1,a=-a; le=1; v[1]=a; while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le; } //Compare --> bool operator ==(const BigNum &a)const{ if (le!=a.le || flag!=a.flag) return 0; for (int i=1;i<=le;++i) if (v[i]!=a.v[i]) return 0; return 1; } bool operator <(const BigNum &a)const{ if (flag<a.flag || flag==a.flag && le<a.le) return 1; if (flag>a.flag || flag==a.flag && le>a.le) return 0; for (int i=le;i>=1;--i){ if (v[i]<a.v[i]) return flag==1? 1:0; if (v[i]>a.v[i]) return flag==1? 0:1; }return 0; } bool operator >(const BigNum &a)const{ if (flag<a.flag || flag==a.flag && le<a.le) return 0; if (flag>a.flag || flag==a.flag && le>a.le) return 1; for (int i=le;i>=1;--i){ if (v[i]<a.v[i]) return flag==1? 0:1; if (v[i]>a.v[i]) return flag==1? 1:0; }return 0; } bool operator ==(const int &x)const{ return *this == BigNum(x); } //Add and Sub --> void operator +=(const BigNum &x){ BigNum a=*this; BigNum b=x; memset(v,0,sizeof v); flag=1; if (a.flag==-1 && b.flag==-1){ flag=-1; a.flag=1; b.flag=1; } if (a < b) swap(a,b); if (b.flag==-1){ b.flag=1; if (a < b) swap(a,b),flag=-1; b.flag=-1; } if (b.flag==1){ le=a.le; for (int i=1;i<=le;++i) v[i]=a.v[i]+b.v[i]; for (int i=1;i<=le;++i) v[i+1]+=v[i]/Base,v[i]%=Base; while (v[le+1]>0) ++le; }else{ le=a.le; for (int i=1;i<=le;++i) v[i]=a.v[i]-b.v[i]; for (int i=1;i<=le;++i) if (v[i]<0) --v[i+1],v[i]+=Base; while (v[le]==0 && le>1) --le; } } void operator +=(int x){ *this += BigNum(x); } void operator -=(const BigNum &x){ BigNum a=x; a.flag=-a.flag; *this += a; } void operator -=(int x){ *this -= BigNum(x); } BigNum &operator ++(){ return *this += 1, *this; } BigNum &operator --(){ return *this -= 1, *this; } BigNum operator ++(int){ BigNum c(*this); ++ *this; return c; } BigNum operator --(int){ BigNum c(*this); -- *this; return c; } //Mul --> void operator *=(const BigNum &x){ BigNum a=x; if (flag==a.flag) flag=1;else flag=-1; a.flag=1; memset(DOF,0,sizeof DOF); for (int i=1;i<=le;++i) for (int j=1;j<=a.le;++j) DOF[i+j-1]+=v[i]*a.v[j]; le+=a.le+9; for (int i=1;i<=le;++i) DOF[i+1]+=DOF[i]/Base,DOF[i]%=Base; while (DOF[le]==0 && le>1) --le; for (int i=1;i<=le;++i) v[i]=DOF[i]; } void operator *=(const int &x){ *this *= BigNum(x); } void operator *=(const LL &x){ *this *= BigNum(x); } //Div --> void operator /=(const int &x){ BigNum a; a=x; if (flag==a.flag) flag=1;else flag=-1; a.flag=1; memset(DOF,0,sizeof DOF); LL rest=0; for (int i=le;i>=1;--i){ rest=rest*Base+v[i]; DOF[i]=rest/x; rest%=x; v[i]=0; } for (int i=le;i>=1;--i) v[i]=DOF[i]; while (v[le]==0 && le>1) --le; } /*void operator /=(const BigNum &x){ BigNum a=*this,b=x,c; if (a.flag==b.flag) flag=1;else flag=-1; a.flag=b.flag=1; if (le-b.le<=3){ LL l=0,r=1e12,ans=-1; while (l<=r){ LL mid=(l+r)>>1; c=b; c*=mid; if (!(c > a)) ans=mid,l=mid+1; else r=mid-1; } *this = BigNum(ans); return; }else{ for (int i=le;i>=1;--i){ int l=0,r=Base,ans=-1; while (l<=r){ int mid=(l+r)>>1; c=BigNum(i,mid); c*=b; if (!(c > a)) ans=mid,l=mid+1; else r=mid-1; } v[i]=ans; c=BigNum(i,ans); c*=b; a-=c; } while (v[le]==0 && le>1) --le; } }*/ void operator /=(const BigNum &x){ BigNum a=*this,b=x,c,d; if (a.flag==b.flag) flag=1;else flag=-1; for (int i=le;i>0;--i) v[i]=0; le=a.le-b.le+1; for (int i=le;i>=1;--i){ //cerr <<i<<endl; c=BigNum(b,i-1); for (int j=log2(Base);j>=0;--j){ d=c; d*=Pw2[j]; if (!(a < d)) v[i]+=Pw2[j],a-=d; } } for (int i=1;i<=le;++i) v[i+1]+=v[i]/Base,v[i]%=Base; while (v[le+1]>0) ++le; while (v[le]==0 && le>1) --le; } //Mod --> void operator %=(int p){ LL d=0; if (p < 0) p=-p; for (int i=le;i>=1;--i) d=(d*Base+v[i])%p,v[i]=0; le=1; v[1]=d; while (v[le]>=Base) v[le+1]+=v[le]/Base,v[le]%=Base,++le; } void operator %=(const BigNum &x){ BigNum a=*this,b=x,c,d; for (int i=le;i>0;--i) v[i]=0; le=a.le-b.le+1; for (int i=le;i>=1;--i){ //cerr <<i<<endl; c=BigNum(b,i-1); for (int j=log2(Base);j>=0;--j){ d=c; d*=Pw2[j]; if (!(a < d)) a-=d; } } *this = a; } //Power --> BigNum pow(int b){ BigNum a,c; a=*this; c=1; for (;b;b>>=1,a*=a) if (b&1) c*=a; return c; } BigNum pow(int x,int b){ BigNum c,a; c=1; a=x; for (;b;b>>=1,a*=a) if (b&1) c*=x; return c; } int pow2(int a,int b){ int c=1; for (;b;b>>=1,a*=a) if (b&1) c*=a; return c; } //Shr and Shl --> void operator <<=(int x){ if (x<=30) *this *= pow2(2,x); else *this *= pow(2,x); } void operator >>=(int x){ if (x<=30) *this /= pow2(2,x); else *this /= pow(2,x); } }; //Compare --> bool operator ==(const int &a,const BigNum &b){ return b == a; } bool operator !=(const BigNum &a,const BigNum &b){ return !(a == b); } bool operator !=(const BigNum &a,const int &b){ return !(a == b); } bool operator !=(const int &a,const BigNum &b){ return !(b == a); } bool operator <(const BigNum &a,const int &b){ return a < BigNum(b); } bool operator <(const int &a,const BigNum &b){ return BigNum(a) < b; } bool operator >(const BigNum &a,const int &b){ return a > BigNum(b); } bool operator >(const int &a,const BigNum &b){ return BigNum(a) > b; } bool operator <=(const BigNum &a,const BigNum &b){ if (a > b) return 0; return 1; } bool operator >=(const BigNum &a,const BigNum &b){ if (a < b) return 0; return 1; } bool operator <=(const BigNum &a,const int &b){ if (a > b) return 0; return 1; } bool operator <=(const int &a,const BigNum &b){ if (a > b) return 0; return 1; } bool operator >=(const BigNum &a,const int &b){ if (a < b) return 0; return 1; } bool operator >=(const int &a,const BigNum &b){ if (a < b) return 0; return 1; } int max(const int &a,const int &b){ if (a < b) return b; return a; } int min(const int &a,const int &b){ if (a < b) return a; return b; } BigNum max(const BigNum &a,const BigNum &b){ if (a < b) return b; return a; } BigNum min(const BigNum &a,const BigNum &b){ if (a < b) return a; return b; } //Add --> BigNum operator +(const BigNum &a,const BigNum &b){ BigNum c=a; c+=b; return c; } BigNum operator +(const BigNum &a,const int &b){ BigNum c=a; c+=b; return c; } BigNum operator +(const int &a,const BigNum &b){ BigNum c=b; c+=a; return c; } //Sub --> BigNum operator -(const BigNum &a,const BigNum &b){ BigNum c=a; c-=b; return c; } BigNum operator -(const BigNum &a,const int &b){ BigNum c=a; c-=b; return c; } BigNum operator -(const int &a,const BigNum &b){ BigNum c=b; c-=a; return c; } //Mul --> BigNum operator *(const BigNum &a,const BigNum &b){ BigNum c=a; c*=b; return c; } BigNum operator *(const BigNum &a,const int &b){ BigNum c=a; c*=b; return c; } BigNum operator *(const int &a,const BigNum &b){ BigNum c=b; c*=a; return c; } //Div --> BigNum operator /(const BigNum &a,const int &b){ BigNum c=a; c/=b; return c; } BigNum operator /(const int &a,const BigNum &b){ BigNum c=b; c/=a; return c; } BigNum operator /(const BigNum &a,const BigNum &b){ BigNum c=a; c/=b; return c; } //Mod --> BigNum operator %(const BigNum &a,const int &b){ BigNum c=a; c%=b; return c; } BigNum operator %(const int &a,const BigNum &b){ BigNum c=b; c%=a; return c; } BigNum operator %(const BigNum &a,const BigNum &b){ BigNum c=a; c%=b; return c; } //Shr and Shl --> BigNum operator <<(const BigNum &a,const int b){ BigNum c=a; c<<=b; return c; } BigNum operator <<(const BigNum &a,BigNum &b){ return a << b.IntoInt(); } BigNum operator >>(const BigNum &a,const int &b){ BigNum c=a; c>>=b; return c; } BigNum operator >>(const BigNum &a,BigNum &b){ return a >> b.IntoInt(); } //Read and Print --> string yz; char cyz; void Read(BigNum &a){ a.Clear(); while (cin.peek()==' ') getchar(); if (cin.peek()=='-'){ a.flag=-1; cin >>cyz; } cin >>yz; int len=yz.length(); a.le=len/Bit; for (int i=1;i<=a.le;++i){ int l=len-Bit*i,r=l+Bit-1; for (int j=l;j<=r;++j) a.v[i]=a.v[i]*10+yz[j]-'0'; } if(len%Bit!=0){ int r=len-Bit*a.le-1; ++a.le; for (int j=0;j<=r;++j) a.v[a.le]=a.v[a.le]*10+yz[j]-'0'; } } void PrintWith(int x,int k){ for (int i=k-1;i>=0;--i) if (Pw10[i]>x) putchar('0'); else putchar(x/Pw10[i]+'0'),x%=Pw10[i]; } void Print(const BigNum &a){ if (a.flag==-1) putchar('-'); printf("%d",a.v[a.le]); for (int i=a.le-1;i>=1;--i) PrintWith(a.v[i],Bit); } void Println(const BigNum &a){ Print(a); puts(""); } }; using namespace BigNumber; BigNum a,ans; int x,b; int main() { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&x); a=2;b=(x+1);ans=1; while(b>0) { if(b%2)ans=ans*a; b=b/2; a=a*a; } ans=ans/3; Println(ans); } return 0; }
第三题
具体思路:莫队
记录一下前缀异或和就好了
AC代码
#include<bits/stdc++.h> using namespace std; #define int long long int n,m,i,j,a[500000],k,ans,L,R,now[500000],sum[500000],answer[500000],tot,num[500000]; struct ask { int l,r,id; }q[500000]; bool cmp(ask a,ask b) { if(num[a.l]!=num[b.l])return (num[a.l])<(num[b.l]);else return a.r<b.r; } void del(int x) { tot-=now[k^sum[x]]; now[sum[x]]--; if(sum[x]==k)tot--; } void add(int x) { tot+=now[k^sum[x]]; now[sum[x]]++; if(sum[x]==k)tot++; } main() { scanf("%lld%lld%lld",&n,&m,&k); for(i=1;i<=n;i++)scanf("%lld",&a[i]),sum[i]=sum[i-1]^a[i],num[i]=i/sqrt(n); for(i=1;i<=m;i++)scanf("%lld%lld",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+1+m,cmp); L=1,R=0; for(i=1;i<=m;i++) { while(L<q[i].l)del(L-1),L++; while(L>q[i].l)L--,add(L-1); while(R<q[i].r)R++,add(R); while(R>q[i].r)del(R),R--; answer[q[i].id]=tot; } for(i=1;i<=m;i++)printf("%lld\n",answer[i]); return 0; }