Educational Codeforces Round 65 (Rated for Div. 2)
A:签到。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define N 110 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int T,n; char s[N]; signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif T=read(); while (T--) { n=read(); scanf("%s",s+1); int first=n; for (int i=1;i<=n;i++) if (s[i]=='8') {first=i;break;} if (n-first+1>=11) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; //NOTICE LONG LONG!!!!! }
B:太难了吧。注意到任意两数乘积不同。于是考虑问出12乘积、34乘积,由此已经可知56乘积。然后需要确定每一对的顺序,可以询问13得到13的值,再询问15得到5的值。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define N 110 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int w[7]={0,4,8,15,16,23,42},a[7]; bool isac(int x) { for (int i=1;i<=6;i++) if (w[i]==x) return 1; return 0; } signed main() { int x,y,z; cout<<"?"<<' '<<1<<' '<<2<<endl;x=read(); cout<<"?"<<' '<<3<<' '<<4<<endl;y=read(); cout<<"?"<<' '<<1<<' '<<3<<endl;z=read(); cout<<"?"<<' '<<1<<' '<<5<<endl;int t=read(); for (int i=1;i<=6;i++) { if (x%w[i]==0&&z%w[i]==0&&t%w[i]==0&&isac(x/w[i])&&isac(z/w[i])&&isac(t/w[i])) { a[1]=w[i]; a[2]=x/w[i]; a[3]=z/w[i]; a[5]=t/w[i]; } } a[4]=y/a[3]; a[6]=1;for (int i=1;i<=6;i++) a[6]*=w[i]; for (int i=1;i<=5;i++) a[6]/=a[i]; cout<<"!"<<' ';for (int i=1;i<=6;i++) cout<<a[i]<<' '; return 0; //NOTICE LONG LONG!!!!! }
C:并查集。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define N 500010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int n,m,a[N],fa[N],size[N]; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} signed main() { n=read(),m=read(); for (int i=1;i<=n;i++) fa[i]=i; for (int i=1;i<=m;i++) { int t=read(); for (int j=1;j<=t;j++) { a[j]=read(); } for (int j=1;j<t;j++) fa[find(a[j])]=find(a[j+1]); } for (int i=1;i<=n;i++) size[find(i)]++; for (int i=1;i<=n;i++) printf("%d ",size[find(i)]); return 0; //NOTICE LONG LONG!!!!! }
D:贪心。左括号分给当前前缀和小的,右括号分给当前前缀和大的。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define N 200010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int n,x,y,a[N]; char s[N]; bool flag[N]; signed main() { n=read(); scanf("%s",s+1); for (int i=1;i<=n;i++) if (s[i]=='(') a[i]=1;else a[i]=-1; for (int i=1;i<=n;i++) if (a[i]==1) { if (x<y) x++,flag[i]=0; else y++,flag[i]=1; } else { if (x>y) x--,flag[i]=0; else y--,flag[i]=1; } for (int i=1;i<=n;i++) printf("%d",flag[i]); return 0; //NOTICE LONG LONG!!!!! }
E:对于确定的右端点r,显然合法的l是一段前缀。考虑先求出令保留[1,l]合法的最大l和令保留[r,m]合法的最小r,然后在范围内twopointers,记一下小于l的值的最晚出现位置和大于r的值的最早出现位置即可。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define N 1000010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int n,m,a[N],mx[N]; vector<int> pos[N]; set<int> q; ll ans; signed main() { n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) pos[a[i]].push_back(i); int p=n+1;int l=m,r=1; for (int i=m;i>=1;i--) { bool flag=0; int x=n+1; for (auto j:pos[i]) { if (j>p) {flag=1;break;} x=min(x,j); } p=min(p,x); if (flag) {r=i;break;} } p=0; for (int i=1;i<=m;i++) { bool flag=0; int x=0; for (auto j:pos[i]) { if (j<p) {flag=1;break;} x=max(x,j); } p=max(p,x); if (flag) {l=i;break;} } int x=1;int y=0; for (int i=r;i<=m;i++) for (auto j:pos[i]) q.insert(j); for (int i=1;i<=m;i++) { for (auto j:pos[i]) mx[i]=max(mx[i],j); } q.insert(n+1); for (int i=r;i<=m;i++) { for (auto j:pos[i]) q.erase(j); while (x<i&&x<l&&max(y,mx[x])<*q.begin()) y=max(y,mx[x++]); ans+=x; } cout<<ans; return 0; //NOTICE LONG LONG!!!!! }
F:考虑每个数的贡献。区间内每有一个数比它小它的贡献次数就+1,初始贡献次数为1。于是考虑所有其他数对该数贡献次数的贡献。对于处于ax和ay的值,显然包含其的区间个数为x*(n-y+1)。于是要求出所有在其前方比它小的数的位置和与所有在其后方比它小的数的位置和。按权值从小到大考虑每个数,树状数组维护即可。wa了两发49简直自闭。
#include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 #define int long long #define N 500010 #define P 1000000007 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} 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; } int n,a[N],b[N],p[N],tree2[N]; ll ans,s,tree[N]; void ins(int x){int k=x;while (k<=n) tree[k]+=x,k+=k&-k;} int query(int k){ll s=0;while (k) s+=tree[k],k-=k&-k;return s%P;} void ins2(int x){while (x<=n) tree2[x]++,x+=x&-x;} int query2(int k){int s=0;while (k) s+=tree2[k],k-=k&-k;return s;} signed main() { n=read(); for (int i=1;i<=n;i++) b[i]=a[i]=read(); sort(b+1,b+n+1); for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b; for (int i=1;i<=n;i++) p[a[i]]=i; for (int i=1;i<=n;i++) { int x=b[i]; ans=(ans+1ll*x*(1ll*p[i]*(n-p[i]+1)%P+1ll*query(p[i])*(n-p[i]+1)%P+1ll*(1ll*(i-1-query2(p[i]))*(n+1)%P+P-(s+P-query(p[i]))%P)%P*p[i]%P)%P)%P; ins(p[i]);ins2(p[i]);s+=p[i]; } cout<<ans%P; return 0; //NOTICE LONG LONG!!!!! }
G:咕了咕了。
小小小号。result:rank 18 rating +239