Educational Codeforces Round 65 (Div. 2)
A.前n-10个有8即合法。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=1010; 10 char s[N]; 11 int T,n; 12 13 int main(){ 14 for (scanf("%d",&T); T--; ){ 15 scanf("%d%s",&n,s+1); bool flag=0; 16 rep(i,1,n-11+1) if (s[i]=='8'){ flag=1; break; } 17 if (flag) puts("YES"); else puts("NO"); 18 } 19 return 0; 20 }
B.这6个数两两乘积不同,于是有多种方法。
(1) (1,1) (2,2) (3,4) (3,5)
(2) (1,2) (3,4) (1,3) (1,5)
(3) (1,2) (2,3) (4,5) (5,6)
(方法三能做7个数的情况)
下面写的是方法一,因为判的情况没写全导致场上FST。
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 7 typedef long long ll; 8 using namespace std; 9 10 const int N=110; 11 int x,y,a[N],b[N]; 12 13 bool ok(int i){ return i==4 || i==8 || i==15 || i==16 || i==23 || i==42; } 14 15 int main(){ 16 puts("? 1 1"); fflush(stdout); scanf("%d",&a[1]); a[1]=sqrt(a[1]); 17 puts("? 2 2"); fflush(stdout); scanf("%d",&a[2]); a[2]=sqrt(a[2]); 18 puts("? 3 4"); fflush(stdout); scanf("%d",&x); 19 puts("? 3 5"); fflush(stdout); scanf("%d",&y); 20 rep(i,4,42) if (ok(i) && (x%i==0) && (y%i==0) && ok(x/i) && ok(y/i)){ 21 rep(j,4,42) b[j]=0; 22 b[a[1]]++; b[a[2]]++; b[i]++; b[x/i]++; b[y/i]++; b[4+8+15+16+23+42-a[1]-a[2]-i-x/i-y/i]++; 23 bool flag=0; 24 rep(j,4,42) if (ok(j) && b[j]!=1){ flag=1; break; } 25 if (flag) continue; 26 printf("! %d %d %d %d %d %d\n",a[1],a[2],i,x/i,y/i,4+8+15+16+23+42-a[1]-a[2]-i-x/i-y/i); break; 27 } 28 return 0; 29 }
C.并查集
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=2000010; 10 int n,m,k,fa[N],sz[N],a[N]; 11 12 int get(int x){ return fa[x]==x ? x : fa[x]=get(fa[x]); } 13 14 int main(){ 15 scanf("%d%d",&n,&m); 16 rep(i,1,n) fa[i]=i,sz[i]=1; 17 rep(i,1,m){ 18 scanf("%d",&k); 19 rep(j,1,k) scanf("%d",&a[j]); 20 rep(j,1,k-1) if (get(a[j])!=get(a[j+1])) sz[get(a[j+1])]+=sz[get(a[j])],fa[get(a[j])]=get(a[j+1]); 21 } 22 rep(i,1,n) printf("%d ",sz[get(i)]); 23 return 0; 24 }
D.贪心
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=400010; 10 int n,x,y,mx,b[N]; 11 char s[N]; 12 13 int main(){ 14 scanf("%d%s",&n,s+1); 15 rep(i,1,n){ 16 if (s[i]=='('){ if (x<=y) x++,b[i]=0; else y++,b[i]=1; } 17 else{ if (x<=y) y--,b[i]=1; else x--,b[i]=0; } 18 } 19 rep(i,1,n) printf("%d",b[i]); 20 return 0; 21 }
E.找到最大的l是的[1,l]的所有数加入序列后都是有序的,同样找到最小的r满足[r,m]的所有数都相对有序,然后two-pointers统计答案即可,细节很多比较难写。
F.对每个数a[i]求它的贡献,也即它在所有包含它的区间中的排名之和。从小到大加数,考虑每个已加的数在多少个区间中对它产生1的贡献,树状数组直接维护即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=500010,mod=1e9+7; 10 int n,m,i,j,a[N],id[N],c1[N],c2[N],ans; 11 12 bool cmp(int x,int y){ return a[x]<a[y]; } 13 void inc(int&x,int v){ x+=v; if(x>=mod)x-=mod; } 14 void add(int c[N],int x,int v){ while (x<=n) inc(c[x],v),x+=x&-x; } 15 int que(int c[N],int x,int res=0){ while (x) inc(res,c[x]),x-=x&-x; return res; } 16 17 int main(){ 18 scanf("%d",&n); 19 rep(i,1,n) scanf("%d",&a[i]),id[i]=i; 20 sort(id+1,id+n+1,cmp); 21 rep(i,1,n){ 22 add(c1,id[i],id[i]); 23 ans=(ans+1ll*a[id[i]]*(1ll*(n-id[i]+1)*que(c1,id[i])%mod+1ll*id[i]*que(c2,n-id[i]+1)%mod)%mod)%mod; 24 add(c2,n-id[i]+1,n-id[i]+1); 25 } 26 printf("%d\n",ans); 27 return 0; 28 }