Codeforces Round #519 by Botan Investments翻車記
阿新 • • 發佈:2018-10-29
元素 img turn obi for 比賽 mes pla getch
A:枚舉答案即可。註意答案最大可達201,因為這個wa了一發瞬間爆炸。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();}View Codewhile (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 110 int n,a[N],mx; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ n=read(); int tot=0; for (int i=1;i<=n;i++) mx=max(mx,a[i]=read()),tot+=a[i];for (int i=mx;i<=201;i++) { int cnt=0; for (int j=1;j<=n;j++) cnt+=i-a[j]; if (cnt>tot) {cout<<i;return 0;} } return 0; }
B:看了半天題。枚舉即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #includeView Code<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 1010 int n,a[N],b[N],cnt=0,c[N]; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int k=1;k<=n;k++) { bool flag=1; for (int i=1;i<=k;i++) b[i]=a[i]-a[i-1]; for (int i=k+1;i<=n;i++) if (a[i]-a[i-1]!=b[(i-1)%k+1]) {flag=0;break;} if (flag) c[++cnt]=k; } cout<<cnt<<endl; for (int i=1;i<=cnt;i++) cout<<c[i]<<‘ ‘; return 0; }
C:看了半天題。想了半天。每次都在字符的分界處翻轉,就可以得到最優解(即a都在前面b都在後面)。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 1010 int n,a[N]; bool flag[N]; char s[N]; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ scanf("%s",s+1); n=strlen(s+1); for (int i=1;i<=n;i++) a[i]=s[i]==‘b‘; for (int i=1;i<=n;i++) { int t=i; while (t<n&&a[t+1]==a[i]) t++; if (t<n||a[i]==0) reverse(a+i+1,a+t+1),flag[t]=1; i=t; } for (int i=1;i<=n;i++) cout<<flag[i]<<‘ ‘; return 0; }View Code
D:看了半天題。暴力匹配,如果失配這些數不可能再被計入答案。這樣分成了很多段,將每段答案加起來即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 100010 #define M 12 int n,m,a[M][N],p[M][N],q[12]; long long ans; bool check() { for (int i=1;i<=m;i++) { q[i]++; if (q[i]>n) return 0; } for (int i=2;i<=m;i++) if (a[i][q[i]]!=a[i-1][q[i-1]]) return 0; return 1; } int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(),m=read(); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) a[i][j]=read(),p[i][a[i][j]]=j; for (int i=1;i<=n;i++) { int x=i; q[1]=i; for (int j=2;j<=m;j++) q[j]=p[j][a[1][i]]; while (x<n&&check()) x++; ans+=1ll*(x-i+2)*(x-i+1)/2; i=x; } cout<<ans; return 0; }View Code
E:看了半天題。看題時間跟想+碼的時間差不多了。首先給出的那些邊顯然可以直接排除。現在要求的是ansi=Σmin(xi+yj,xj+yi),可以將其變成ansi=Σmin(xi-yi-xj+yj,0)+xj+yi。這樣min裏面的東西只需要二分查一個前綴和。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 300010 int n,m,t=0; long long ans[N],b[N],pre[N],sum; struct data{int x,y; }a[N]; int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(),m=read(); for (int i=1;i<=n;i++) sum+=a[i].x=read(),a[i].y=read(),b[i]=a[i].y-a[i].x; sort(b+1,b+n+1); for (int i=1;i<=n;i++) pre[i]=pre[i-1]+b[i]; for (int i=1;i<=m;i++) { int x=read(),y=read(); ans[x]-=min(a[x].x+a[y].y,a[x].y+a[y].x),ans[y]-=min(a[x].x+a[y].y,a[x].y+a[y].x); } /*for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (i!=j) ans[i]+=min(a[i].x-a[i].y+b[j],0)+a[i].y+a[j].x;*/ for (int i=1;i<=n;i++) { ans[i]+=sum-a[i].x+1ll*a[i].y*(n-1); int l=1,r=n,t=0; while (l<=r) { int mid=l+r>>1; if (b[mid]+a[i].x-a[i].y<0) t=mid,l=mid+1; else r=mid-1; } ans[i]+=pre[t]+1ll*t*(a[i].x-a[i].y); } for (int i=1;i<=n;i++) printf("%I64d ",ans[i]); return 0; } closeView Code
F:做法似乎很多。比賽時只想到設f[i]為gcd=i時最少選多少元素,考慮通過與i的gcd數量是i的因子個數來優化,預處理可以向哪轉移。這一部分看起來可以瞎優化到不錯的效率,然而又wa又T最後棄療了。
題解給的是狀壓dp,沒有太懂。似乎也有不少隨機化做法。
感覺最妙的做法還是這樣:強化這個題,求選k個數時的方案數。這顯然可以莫比烏斯反演,預處理每個數在a中有多少個是其倍數即可,這可以利用調和級數做到log。顯然最終答案若存在一定不超過7,於是復雜度O(n+vlogv)。這應該是保證正確性(取模後變成0什麽的就算了吧)的最優做法了。把一個判定性問題轉化為數數題居然能夠簡化問題非常有意思。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1;c=getchar();} while (c>=‘0‘&&c<=‘9‘) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 300010 #define P 1000000007 int n,a[N],mobius[N],prime[N],tot[N],cnt; int fac[N],inv[N]; bool flag[N]; int C(int n,int m) { if (m>n) return 0; return 1ll*fac[n]*inv[m]%P*inv[n-m]%P; } int main() { #ifndef ONLINE_JUDGE freopen("f.in","r",stdin); freopen("f.out","w",stdout); #endif n=read(); for (int i=1;i<=n;i++) a[read()]++; flag[1]=1;mobius[1]=1; for (int i=2;i<=N-10;i++) { if (!flag[i]) prime[++cnt]=i,mobius[i]=-1; for (int j=1;j<=cnt&&prime[j]*i<=N-10;j++) { flag[prime[j]*i]=1; if (i%prime[j]==0) break; else mobius[prime[j]*i]=-mobius[i]; } } fac[0]=1;for (int i=1;i<=N-10;i++) fac[i]=1ll*fac[i-1]*i%P; inv[0]=inv[1]=1;for (int i=2;i<=N-10;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P; for (int i=2;i<=N-10;i++) inv[i]=1ll*inv[i-1]*inv[i]%P; for (int i=1;i<=N-10;i++) for (int j=i;j<=N-10;j+=i) tot[i]+=a[j]; for (int k=1;k<=7;k++) { int ans=0; for (int i=1;i<=N-10;i++) ans=((ans+mobius[i]*C(tot[i],k))%P+P)%P; if (ans) {cout<<k;return 0;} } cout<<-1; return 0; }View Code
這場閱讀量實在太大,讀題感覺花了快有30min。A wa一發掉了至少30名非常慘了。
result:rank 417 rating -6
Codeforces Round #519 by Botan Investments翻車記