Day1 210pts(含T1莫名的-10pts和T3莫名的-30pts)
100+70+40=210
rank 29
这道题第一眼看是字符串匹配问题什么KMP啊,又想KMP不会做啊,那就RK Hash 吧,结果Hash打了一半发现Hint:要全排列,
然后掐指一算3000!一定爆所以换思路,对于区间[l,r]字符种类和对应数目与前面那个串完全相同就是一个匹配,常数是52,应该能过
# include <bits/stdc++.h> using namespace std; char a[3005],b[3000005]; int sta[120],stb[120],lena,lenb; int fun(char ch) { if ('A'<=ch&&ch<='Z') return ch-'A'+1; else return ch-'a'+1+26; } bool check() { for (int i=1;i<=52;i++) if (sta[i]!=stb[i]) return false; return true; } int main() { freopen("mayan.in","r",stdin); freopen("mayan.out","w",stdout); int t1,t2; scanf("%d%d",&t1,&t2); getchar(); for (int i=1;i<=t1;i++) a[i]=getchar(); getchar();lena=t1; for (int i=1;i<=t2;i++) b[i]=getchar(); getchar();lenb=t2; for (int i=1;i<=lena;i++) {sta[fun(a[i])]++;} int ans=0; for (int i=1;i<=lenb;i++) { if (i<=lena-1) { stb[fun(b[i])]++;continue;} else if (i==lena) { stb[fun(b[i])]++; if (check()) ans++; continue; } stb[fun(b[i-lena])]--; stb[fun(b[i])]++; if (check()) ans++; } printf("%d ",ans); return 0; }
事情是这样的,求形如(a...a)(b....b)或(a.....a)的子序列个数
如abba中{a,b,ab,bb,ba,abb,bba}有且有7个
于是考场上写出20行的STL代码,70分!跟我一起念:STL大法好qwq
70pts(MLE/TLE)
# include <bits/stdc++.h> using namespace std; set<string>stt; string s; int main() { freopen("strange.in","r",stdin); freopen("strange.out","w",stdout); cin>>s; int len=s.length(); char ch1,ch2; for (int i=0;i<len;i++) { ch1=s[i]; int j=i; while (j<len&&s[j]==ch1) { j++; stt.insert(s.substr(i,j-i));} ch2=s[j]; while (j<len&&s[j]==ch2) { j++; stt.insert(s.substr(i,j-i));} } int ans=0,i; printf("%d ",stt.size()); return 0; }
好了讲正解,vector[i][j]表示形如(i....i)(j....j)的二元组(x,y)表示有x个i,y个j组成,然后就会对于每个vecort都会有二元组,然后面积求和即可
然后把所有面积的并集求出来就是vector[i][j]的值,然后把各值求出来累加就行了。
# include <bits/stdc++.h> using namespace std; struct Node{ int x,y; }; vector <Node> a[27][27]; Node m[200005]; int n; bool cmp(Node aa,Node bb) { if (aa.x!=bb.x) return aa.x>bb.x; else return aa.y>bb.y; } char s[200005]; int fun() { sort(m+1,m+1+n,cmp); int X=m[1].x,Y=m[1].y; int S=X*Y; for (int i=2;i<=n;i++) if (m[i].y>Y) { S=S+(m[i].y-Y)*m[i].x; X=m[i].x;Y=m[i].y; } return S; } int main() { scanf("%s",s+1); int len=strlen(s+1); int i; for (i=1;i<=len;i++) { char ch1,ch2; int cnt1=0,cnt2=0; ch1=s[i]; int j=i; while (j<=len&&s[j]==ch1) j++,cnt1++; if (j>len) j=len; ch2=s[j]; int kk=j-1; while (j<=len&&s[j]==ch2) j++,cnt2++; if (ch1==ch2) continue; Node N; N.x=cnt1; N.y=cnt2; a[ch1-'a'+1][ch2-'a'+1].push_back(N); i=kk; } int ans=0; for (int i=1;i<=26;i++) for (int j=1;j<=26;j++) { n=(int)(a[i][j].size()); memset(m,0,sizeof(m)); for (int k=1;k<=n;k++) m[k]=a[i][j][k-1]; ans=ans+fun(); } for (int i=1;i<=26;i++) { int cnt=0,maxx=0; bool flag=false; for (int j=1;j<=len;j++) if (s[j]==i+'a'-1) flag=true; for (int j=1;j<=len;j++) { while (s[j]==i+'a'-1&&s[j+1]==i+'a'-1&&j<len) j++,cnt++; maxx=max(maxx,cnt); cnt=0; } if (flag)ans=ans+maxx+1; } printf("%d ",ans); return 0; }
std:
#include <bits/stdc++.h> using namespace std; template <typename T> void read(T &t) { char ch=getchar(); int f=1; t=0; while ('0'>ch||ch>'9') { if (ch=='-') f=-1; ch=getchar(); } do { (t*=10)+=ch-'0'; ch=getchar(); } while ('0'<=ch&&ch<='9'); t*=f; } typedef long long ll; const int maxn=100010; int n,k,x[maxn],a[maxn],sz; map<int,int> m; ll ans; int main() { read(n); read(k); for (int i=1;i<=n;i++) { read(x[i]); m[x[i]]++; } sort(x+1,x+(n+1)); for (int i=1;i<=n;i++) if (x[i]!=x[i-1]) a[++sz]=x[i]; int pos=0,c1=0,c2=0; for (int i=1;i<=sz;i++) { while (pos<sz&&a[pos+1]<=(ll)a[i]*k) { pos++; if (m[a[pos]]>=2) c1++; else c2++; } int v=0; if (m[a[i]]>=2) v++; int s=c1+c2-1; ans+=3*(c1-v); if (s>1) ans+=3LL*s*(s-1); if (m[a[i]]>=2) ans+=3*(c1+c2-1); if (m[a[i]]>=3) ans++; if (m[a[i]]>=2) c1--; else c2--; } cout<<ans<<endl; return 0; }