这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
2020-2021:teams:die_java:front_page_summertrain2 [2020/07/17 17:51] mychael |
2020-2021:teams:die_java:front_page_summertrain2 [2020/10/17 23:02] (当前版本) fyhssgss |
||
---|---|---|---|
行 11: | 行 11: | ||
===== 题解 ===== | ===== 题解 ===== | ||
- | ===== 题目名字 ===== | + | ===== B.Boundary ===== |
=== 题意 === | === 题意 === | ||
+ | |||
+ | 给了n个点,画一个过原点的圆,问最多能有多少个点在圆上。 | ||
=== 题解 === | === 题解 === | ||
+ | 我们固定原点和一个点,枚举剩下的点,求出这三个点的圆心,答案即为重合最多的圆心数加一。题目有点卡常,用分数计算会超时,无奈只能用double记录点玄学通过。 | ||
+ | |||
+ | <hidden 代码> | ||
<code cpp> | <code cpp> | ||
+ | #include<bits/stdc++.h> | ||
+ | using namespace std; | ||
+ | #define mem(a,b) memset(a,b,sizeof(a)) | ||
+ | typedef long long LL; | ||
+ | typedef pair<LL,LL> PII; | ||
+ | typedef pair<double,double> PDD; | ||
+ | #define X first | ||
+ | #define Y second | ||
+ | inline int read() | ||
+ | { | ||
+ | int x=0,f=1;char c=getchar(); | ||
+ | while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} | ||
+ | while(isdigit(c)){x=x*10+c-'0';c=getchar();} | ||
+ | return x*f; | ||
+ | } | ||
+ | const int N=2000055; | ||
+ | const int maxn=2010; | ||
+ | PII A[maxn]; | ||
+ | LL aa[N]; | ||
+ | int n,ans,sum; | ||
+ | map<PDD,int> mp; | ||
+ | LL gcd(LL a,LL b){return b==0 ? a : gcd(b,a%b);} | ||
+ | int main() | ||
+ | { | ||
+ | n=read(); | ||
+ | for(int i=1;i<=n;i++)scanf("%lld%lld",&A[i].X,&A[i].Y); | ||
+ | for(int i=1;i<n;i++) | ||
+ | { | ||
+ | mp.clear(); | ||
+ | for(int j=i+1;j<=n;j++) | ||
+ | { | ||
+ | LL a=A[i].X,b=A[i].Y,c=A[j].X,d=A[j].Y; | ||
+ | if(b*c-a*d==0) continue; | ||
+ | LL p=a*a+b*b,q=c*c+d*d,r=b*c-a*d; | ||
+ | LL x1=q*b-p*d,x2=r; | ||
+ | LL y1=p*c-q*a,y2=r; | ||
+ | // LL xx=gcd(abs(x1),abs(x2)),yy=gcd(abs(y1),abs(y2)); | ||
+ | double xx=1.*x1/x2; | ||
+ | double yy=1.*y1/y2; | ||
+ | /* if(x1<0) 分数做法 | ||
+ | { | ||
+ | x1*=-1;x2*=-1; | ||
+ | } | ||
+ | else if(x1==0) | ||
+ | { | ||
+ | x2=1;xx=1; | ||
+ | } | ||
+ | if(y1<0) | ||
+ | { | ||
+ | y1*=-1;y2*=-1; | ||
+ | } | ||
+ | else if(y1==0) | ||
+ | { | ||
+ | y2=1;yy=1; | ||
+ | } | ||
+ | x1/=xx;x2/=xx;y1/=yy;y2/=yy; | ||
+ | LL hs2=0; | ||
+ | hs2=hs2*998244353+x1;hs2=hs2*998244353+x2; | ||
+ | hs2=hs2*998244353+y1;hs2=hs2*998244353+y2; | ||
+ | // printf("%d %d %lld %lld %lld %lld\n",i,j,x1,x2,y1,y2); | ||
+ | // aa[++sum]=hs2;*/ | ||
+ | ans=max(ans,++mp[PDD(xx,yy)]); | ||
+ | } | ||
+ | } | ||
+ | /* sort(aa+1,aa+1+sum); | ||
+ | for(int i=1;i<=sum;i++) | ||
+ | { | ||
+ | int tot=1; | ||
+ | for(int j=i+1;j<=sum;j++) | ||
+ | { | ||
+ | if(aa[j]==aa[i]) tot++; | ||
+ | else break; | ||
+ | } | ||
+ | ans=max(ans,tot); | ||
+ | i+=tot-1; | ||
+ | }*/ | ||
+ | printf("%d\n",++ans); | ||
+ | return 0; | ||
+ | } | ||
</code> | </code> | ||
+ | </hidden> | ||
===== C.Cover the Tree ===== | ===== C.Cover the Tree ===== | ||
行 155: | 行 239: | ||
水题 | 水题 | ||
+ | ===== E.Exclusive OR ===== | ||
+ | |||
+ | === 题意 === | ||
+ | |||
+ | 给了 $n$ 个数,让你求 $1 \le i \le n$ ,选 $i$ 个数(可以选相同的数)异或和的最大值。 | ||
+ | |||
+ | === 题解 === | ||
+ | |||
+ | 发现 $i$ 在19之后答案和 $i-2$ 一致,原理参考线性基。所以我们只需求前19个的答案,用FWT即可完成。 | ||
+ | |||
+ | <hidden 代码> | ||
+ | <code cpp> | ||
+ | #include<iostream> | ||
+ | #include<cstdio> | ||
+ | #include<algorithm> | ||
+ | #include<cstring> | ||
+ | #define ll long long | ||
+ | using namespace std; | ||
+ | int read() | ||
+ | { | ||
+ | int k=0,f=1;char c=getchar(); | ||
+ | for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; | ||
+ | for(;isdigit(c);c=getchar()) k=k*10+c-'0';return k*f; | ||
+ | } | ||
+ | const int M=1050000; | ||
+ | int n,N,a[M],b[M],c[M],ans[M]; | ||
+ | void FWT(int *a,int opt) | ||
+ | { | ||
+ | for(int i=1;i<N;i<<=1) | ||
+ | for(int p=i<<1,j=0;j<N;j+=p) | ||
+ | for(int k=0;k<i;++k) | ||
+ | { | ||
+ | int X=a[j+k],Y=a[i+j+k]; | ||
+ | a[j+k]=(X+Y);a[i+j+k]=(X-Y); | ||
+ | if(opt==-1)a[j+k]=1ll*a[j+k]/2,a[i+j+k]=1ll*a[i+j+k]/2; | ||
+ | } | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | n=read();int mx=0,x; | ||
+ | for(int i=1;i<=n;i++) | ||
+ | { | ||
+ | x=read(); | ||
+ | a[x]=1;b[x]=1;mx=max(mx,x); | ||
+ | } | ||
+ | for(N=1;N<=mx;N<<=1); | ||
+ | ans[1]=mx; | ||
+ | FWT(b,1); | ||
+ | for(int i=2;i<=min(25,n);i++) | ||
+ | { | ||
+ | for(int j=0;j<N;j++) | ||
+ | if(a[j]) a[j]=1; | ||
+ | FWT(a,1); | ||
+ | for(int j=0;j<N;j++) | ||
+ | a[j]=a[j]*b[j]; | ||
+ | FWT(a,-1); | ||
+ | for(int j=N-1;j>=0;j--) | ||
+ | { | ||
+ | if(a[j]) {ans[i]=j;break;} | ||
+ | } | ||
+ | // for(int j=0;j<N;j++) | ||
+ | // cout<<a[j]<<" "; | ||
+ | // cout<<endl; | ||
+ | } | ||
+ | for(int i=1;i<=n;i++) | ||
+ | { | ||
+ | if(i>25) | ||
+ | { | ||
+ | if(i&1) printf("%d ",ans[25]); | ||
+ | else printf("%d ",ans[24]); | ||
+ | } | ||
+ | else printf("%d ",ans[i]); | ||
+ | } | ||
+ | puts(""); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | </hidden> | ||
===== F.Fake Maxpooling ===== | ===== F.Fake Maxpooling ===== | ||
行 378: | 行 540: | ||
</code> | </code> | ||
</hidden> | </hidden> | ||
- | ===== 题目名字 ===== | ||
- | === 题意 === | ||
- | |||
- | === 题解 === | ||
- | |||
- | <code cpp> | ||
- | |||
- | </code> | ||
===== J.Just Shuffle ===== | ===== J.Just Shuffle ===== | ||