牛客NOIP暑期七天营-提高组2C:滑块(平衡树) (这里rope骗分)

A:hash 或者 map 或者trie。

#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
",ans);
    return 0;
}
View Code

B:贪心+大讨论,或者预处理+二分。

#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;
}
View Code

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
",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;
}
原文地址:https://www.cnblogs.com/hua-dong/p/11383939.html