牛客NOIP暑期七天营-提高组2C:滑块(平衡树) (这里rope骗分)
A:hash 或者 map 或者trie。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=200010; map<vector<char>,int>mp; char c[maxn][22]; vector<char>S; int main() { int N,M,ans=0; scanf("%d",&N); rep(i,1,N){ scanf("%s",c[i]); if(c[i][0]=='T'||c[i][0]=='G'){ int len=strlen(c[i]); S.clear(); rep(j,0,len-1) S.push_back(c[i][j]); mp[S]++; } } rep(i,1,N) { if(c[i][0]=='A'||c[i][0]=='C') { int len=strlen(c[i]); S.clear(); rep(j,0,len-1){ if(c[i][j]=='A') S.push_back('T'); if(c[i][j]=='T') S.push_back('A'); if(c[i][j]=='C') S.push_back('G'); if(c[i][j]=='G') S.push_back('C'); } if(mp[S]>=1) ans++,mp[S]--; } } printf("%d\n",ans); return 0; }
B:贪心+大讨论,或者预处理+二分。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ll unsigned long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=200010; char c[maxn]; ll a[maxn]; int tot; void dfs(int L,int A,int B,ll sum) { if(A!=0&&B!=0&&A==B) { a[++tot]=sum; } if(L==18) return ; dfs(L+1,A+1,B,sum*10+4); dfs(L+1,A,B+1,sum*10+7); } int main() { dfs(0,0,0,0); sort(a+1,a+tot+1); int T,N; scanf("%d",&T); while(T--){ scanf("%s",c+1); int N=strlen(c+1); if(N==20) { rep(i,1,10) putchar('4'); rep(i,1,10) putchar('7'); puts(""); } else if(N&1){ rep(i,1,N/2+1) putchar('4'); rep(i,1,N/2+1) putchar('7'); puts(""); } else { ll x=0; rep(i,1,N) x=x*10+c[i]-'0'; int p=lower_bound(a+1,a+tot+1,x)-a; if(p==tot+1){ rep(i,1,N/2+1) putchar('4'); rep(i,1,N/2+1) putchar('7'); puts(""); } else cout<<a[p]<<endl; } } return 0; }
C:主要是想说明一下,这个rope真的妙。
题意:三者操作,(1,x)表示询问x柱子上最长的且最后的连续0的区间。 (2,num,col)表示新建一个柱子,上面有num个col。 (3,x,y,z)是把x柱子加入到y的z位置后面。
显然是平衡树的题,但是我觉得很难操作,还不如骗分,所以就想了下rope,对于新建和插入,都可以用rope高效实现,只有询问操作,我是暴力的。
#include<bits/stdc++.h> #include<ext/rope> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; using namespace __gnu_cxx; const int maxn=2000010; rope<int>a[maxn],b[maxn]; int P,L[maxn]; void read(int &x){ x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); } int main() { int N,opt,num,col,x,y,z,o; scanf("%d",&N); rep(i,1,N) { read(opt); if(opt==1){ read(x); int l=0,r=0,res=0; for(int i=L[x]-1;i>=0;i--){ if(a[x][i]==1) continue; else { int j=i; while(j>0&&a[x][j-1]==0) j--; if(i-j+1>res) l=j+1,r=i+1,res=i-j+1; i=j; } } printf("%d %d\n",l,r); } else if(opt==2){ read(num); read(col); P++; //rep(i,1,num){ a[P].insert(L[P],num,col); L[P]+=num; //} } else { read(x); read(y); read(z); read(o); a[y].insert(z,a[x]); L[y]+=L[x]; if(o==0) a[x].clear(),L[x]=0; } } return 0; }
It is your time to fight!