因为这次难得不在十点半(或是更晚),大家都在打,然后我又双叒叕垫底了=。=
多打CF
A.Sea Battle
讨论.jpg
也有式子的解法,我没想
B.Draw
讨论失败.jpg
(写题顺序:ADFC,没有B)
讨论个**,转化成线段求交,答案就是$sum max(0,min(x,y)-max(lstx,lsty)+(lstx!=lsty))$,记得加上一开始的1
C.Birthday
赛场降智->枚举两边$n^2$+排序后中间轮着放检查$n$->$n^3$睿智算法
正确答案->不知为啥还要枚举,排序以后直接轮着放->$nlog n$
D.Gourmet choice
并查集+拓扑排序

1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=2005,M=2000005; 7 int num[N],aset[N],que[N],bel[N]; 8 int p[N],noww[M],goal[M],deg[N]; 9 int n,m,f,b,t1,t2,cnt,tot,ff; 10 char rd[1005][1005]; 11 int Finda(int x) 12 { 13 return x==aset[x]?x:aset[x]=Finda(aset[x]); 14 } 15 void Link(int f,int t) 16 { 17 noww[++cnt]=p[f],deg[t]++; 18 goal[cnt]=t,p[f]=cnt; 19 } 20 int main () 21 { 22 scanf("%d%d",&n,&m); 23 for(int i=1;i<=n+m;i++) aset[i]=i; 24 for(int i=1;i<=n;i++) 25 { 26 scanf("%s",rd[i]+1); 27 for(int j=1;j<=m;j++) 28 if(rd[i][j]=='=') 29 aset[Finda(i)]=Finda(j+n); 30 } 31 for(int i=1;i<=n+m;i++) bel[i]=Finda(i); 32 for(int i=1;i<=n;i++) 33 for(int j=1;j<=m;j++) 34 { 35 if(rd[i][j]=='<') Link(bel[i],bel[j+n]); 36 if(rd[i][j]=='>') Link(bel[j+n],bel[i]); 37 } 38 for(int i=1;i<=n+m;i++) 39 if(!deg[i]) que[++b]=i,num[i]=1; 40 while(f<=b) 41 { 42 int tn=que[f++]; 43 for(int i=p[tn];i;i=noww[i]) 44 if(!(--deg[goal[i]])) 45 que[++b]=goal[i],num[goal[i]]=num[tn]+1; 46 } 47 for(int i=1;i<=n+m;i++) if(deg[i]) printf("No"),exit(0); puts("Yes"); 48 for(int i=1;i<=n;i++) printf("%d ",num[bel[i]]); puts(""); 49 for(int i=n+1;i<=n+m;i++) printf("%d ",num[bel[i]]); 50 return 0; 51 }
E.String Multiplication
请讨论.jpg
答案只和最大子段,前缀连续和后缀连续有关,枚举哪个字符作为答案之后再统计就比较简单了
但是仍然有很多细节=。=

#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=100005; string str[N]; long long ans; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>str[i]; for(int i='a';i<='z';i++) { long long maxi=0; for(int j=1;j<=n;j++) { int len=str[j].size(); long long lst=0,tmp=0,pre=0,suf=0; for(int k=0;k<len;k++) (str[j][k]==i)?lst=max(lst,++tmp):tmp=0; if(lst||maxi) { for(int k=0;k<len;k++) if(str[j][k]==i) pre++; else break; for(int k=len-1;~k;k--) if(str[j][k]==i) suf++; else break; if(lst==len) maxi=(maxi+1)*lst+maxi; else maxi=maxi?max(lst,pre+suf+1):lst; } } ans=max(ans,maxi); } printf("%lld",ans); return 0; }
F.Asya And Kittens
并查集维护小猫之间的连通性,同时维护每只小猫的下一只小猫和当前小猫链里最后一只小猫是谁。

1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=150005; 6 int n,st,t1,t2,cnt; 7 int aset[N],nxt[N],endp[N]; 8 int Finda(int x) 9 { 10 return x==aset[x]?x:aset[x]=Finda(aset[x]); 11 } 12 int main() 13 { 14 scanf("%d",&n); 15 for(int i=1;i<=n;i++) aset[i]=endp[i]=nxt[i]=i; 16 for(int i=1;i<n;i++) 17 { 18 scanf("%d%d",&t1,&t2); 19 int t3=Finda(t1),t4=Finda(t2); 20 aset[t3]=t4,nxt[endp[t4]]=t3,endp[t4]=endp[t3]; 21 } 22 for(int i=1;i<=n;i++) 23 if(Finda(i)==i) {st=i; break;} 24 while(nxt[st]!=st) 25 printf("%d ",st),st=nxt[st]; 26 printf("%d",st); 27 return 0; 28 }
G.Most Dangerous Shark
单调栈优化DP,代码咕咕了