zoukankan      html  css  js  c++  java
  • CF1037简要题解

     

    A:FJOI 神秘数的第一部分,事实上答案是 $log_2 n$ 。

    B:中位数定在中间后计算偏移值。

    C:只有在相邻时 $2$ 操作比 $1$ 操作优,简单判断即可。

    D:模拟题。

    E:如果没有加边操作,那么就是经典类似拓扑删边,那么不妨将操作序列倒过来开每条边是否在答案中。

    F:考虑求的是什么,不难发现答案为 $sum_{l,r,k-1|(r-l)} max{A_l,A_{l+1},...,A_r}$ ,那么我们将 $imod k-1$ 相同的看成一族同一处理那么问题变成求 $sum_{1leq l<r} max{W_l,W_{l+1},...,W_r}$  ,拿单调队列加单调栈即可解决。

    G:用 $SG$ 函数求解,考虑 $SG(l,r)$ 的计算是枚举字符然后划分出若干子区间分别异或在取 $mex$ ,对于一个区间的两边均为同一个字符的可以预处理,那么只要处理前缀和后缀,这个可以记忆化得出,因为这种区间最多不超过 $O(26n)$ 。

    H:$SAM$ 维护 $endpos$ 模板题。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    int N,Ans,R;
    int main(){
        N=read();
        while(R<N){
            Ans++; R+=(R+1);
        }
        printf("%d
    ",Ans); return 0;
    }
    A
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define int long long
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=2e5+11;
    int N,S,A[MAXN];
    signed main(){
        N=read(),S=read();
        for(int i=1;i<=N;i++) A[i]=read();
        sort(A+1,A+N+1);
        int ps=(N+1)/2,Ans=abs(A[ps]-S);
        for(int j=1;j<ps;j++){
            if(A[j]>S) Ans+=A[j]-S;
        }
        for(int j=ps+1;j<=N;j++){
            if(A[j]<S) Ans+=S-A[j];
        }
        printf("%lld
    ",Ans); return 0;
    }
    B
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1e6+11;
    int N,Ans; char S[MAXN],T[MAXN];
    bool vis[MAXN];
    int main(){
        N=read(); scanf("%s%s",S+1,T+1);
        for(int i=1;i<=N;i++){
            if(vis[i]) continue;
            if(i!=N){
                if(S[i]!=T[i]&&S[i+1]!=T[i+1]&&S[i]!=S[i+1]){
                    Ans++; vis[i+1]=1;
                    continue;
                }
            }
            if(S[i]!=T[i]) Ans++;
        }
        printf("%d
    ",Ans); return 0;
    }
    C
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1e6+11;
    int N,Ans; char S[MAXN],T[MAXN];
    bool vis[MAXN];
    int main(){
        N=read(); scanf("%s%s",S+1,T+1);
        for(int i=1;i<=N;i++){
            if(vis[i]) continue;
            if(i!=N){
                if(S[i]!=T[i]&&S[i+1]!=T[i+1]&&S[i]!=S[i+1]){
                    Ans++; vis[i+1]=1;
                    continue;
                }
            }
            if(S[i]!=T[i]) Ans++;
        }
        printf("%d
    ",Ans); return 0;
    }
    D
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<queue>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=2e5+11;
    vector<pii> vec[MAXN];
    int N,M,d[MAXN],U[MAXN],V[MAXN],K,Ans[MAXN];
    bool vis[MAXN]; queue<int> que;
    int main(){
        //freopen("5.in","r",stdin);
        N=read(),M=read(),K=read();
        for(int i=1;i<=N;i++) vis[i]=1;
        for(int i=1;i<=M;i++) U[i]=read(),V[i]=read(),d[U[i]]++,d[V[i]]++,vec[U[i]].pb(mp(V[i],i)),vec[V[i]].pb(mp(U[i],i));
        for(int i=1;i<=N;i++) if(d[i]<K) que.push(i);
        while(!que.empty()){
            int xx=que.front(); vis[xx]=0; que.pop();
            for(auto pp:vec[xx]){
                int v=pp.fi,t=pp.se; d[v]--;
                if(d[v]==K-1) que.push(v);
            }
        }
        int res=0; for(int i=1;i<=N;i++) res+=vis[i]; 
        Ans[M]=res;
        for(int i=M;i>=2;i--){
            int u=U[i],v=V[i];
            //cerr<<u<<" "<<v<<" "<<vis[u]<<" "<<vis[v]<<" "<<res<<endl;
            if(vis[u]&&vis[v]){
                d[u]--; if(d[u]<K) que.push(u),vis[u]=0;
                d[v]--; if(d[v]<K) que.push(v),vis[v]=0;
                while(!que.empty()){
                    int xx=que.front(); res--; que.pop();
                    for(auto pp:vec[xx]){
                        int vv=pp.fi,t=pp.se; 
                        if(t>=i) continue;
                        d[vv]--;
                        if(d[vv]==K-1&&vis[vv]) vis[vv]=0,que.push(vv);
                    }
                }
            }
            Ans[i-1]=res;
            //for(int j=1;j<=N;j++) cerr<<d[j]<<" ";cerr<<endl;
        }
        for(int i=1;i<=M;i++) printf("%d
    ",Ans[i]); return 0;
    }/*
    5 7 2
    1 5
    3 2
    2 5
    3 4
    1 2
    5 3
    1 3
    */
    E
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define int long long
    #define mod 1000000007
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1e6+11;
    deque<int> que; int N,A[MAXN],K,W[MAXN];
    int sta[MAXN],tot,vis[MAXN],Ans;
    int Query(int x){return (x+K-2)/(K-1);}
    signed main(){
        //freopen("7.in","r",stdin);
        N=read(),K=read(); for(int i=1;i<=N;i++) A[i]=read();
        for(int i=1;i<=N;i++){
            while(!que.empty()&&que.front()<=i-K) que.pop_front();
            while(!que.empty()&&A[que.back()]<=A[i]) que.pop_back();
            que.push_back(i); 
            if(i>=K) W[i]=A[que.front()];
        }
        //for(int i=1;i<=N;i++) cerr<<W[i]<<" ";cerr<<endl;
        for(int i=1;i<=N;i++) if(!vis[i]){
            sta[0]=0; int sum=0,tot=0;
            for(int j=i;j<=N;j+=(K-1)){
                vis[j]=1;
                while(tot&&W[sta[tot]]<=W[j]){
                    sum-=W[sta[tot]]*((Query(sta[tot])-Query(sta[tot-1]?sta[tot-1]:i)));
                    sum=((sum%mod)+mod)%mod;
                    tot--;
                }
                if(j!=i){
                    sta[++tot]=j;
                    sum+=W[sta[tot]]*((Query(sta[tot])-Query(sta[tot-1]?sta[tot-1]:i)));
                    sum%=mod;
                    //cerr<<"j:"<<j<<" sum:"<<sum<<endl;
                }
                //cerr<<sta[tot]<<" "<<sta[tot]-sta[tot-1]<<endl;
                //cerr<<"j:"<<j<<" sum:"<<sum<<endl;
                Ans+=sum; Ans%=mod;
            }
        }
        printf("%lld
    ",Ans); return 0;
    }
    /*
    6 3
    6 5 4 3 2 1
    */
    /*
    5 3
    5 8 7 1 9
    */
    F
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1e5+11;
    char S[MAXN]; 
    int N,f[MAXN][26],F[MAXN][26],g[MAXN],pre[MAXN][26],suf[MAXN][26],Vis[MAXN],Q;
    int calc(int L,int R){
        if(L>R) return 0;
        int sta[28];sta[0]=0;
        for(int c=0;c<26;c++){
            int l=suf[L][c],r=pre[R][c]; if(l>r) continue;
            int res=g[r]^g[l];
            if(L<=l-1) res^=f[l-1][S[L-1]-'a'];
            if(r+1<=R){
                if(f[R][S[r]-'a']!=-1) res^=f[R][S[r]-'a'];
                else{
                    int x=calc(r+1,R); res^=x; f[R][S[r]-'a']=x;
                }
            }
            sta[++sta[0]]=res;
        }
        for(int i=1;i<=sta[0];i++) Vis[sta[i]]=1;
        int ps=0; while(Vis[ps]) ++ps;
        for(int i=1;i<=sta[0];i++) Vis[sta[i]]=0;
        sta[0]=0;
        return ps;
    }
    int Solve(int L,int R){
        if(L>R) return 0;
        int sta[28]; sta[0]=0;
        for(int c=0;c<26;c++){
            int l=suf[L][c],r=pre[R][c]; if(l>r) continue;
            int res=g[r]^g[l];
            if(L<=l-1){
                if(F[L][c]==-1){int x=Solve(L,l-1); F[L][c]=x; }
                res^=F[L][c];
            }
            if(r+1<=R) res^=f[R][S[r]-'a'];
            sta[++sta[0]]=res;
        }
        for(int i=1;i<=sta[0];i++) Vis[sta[i]]=1;
        int ps=0; while(Vis[ps]) ++ps;
        for(int i=1;i<=sta[0];i++) Vis[sta[i]]=0;
        sta[0]=0;
        return ps;
    }
    int main(){
        //freopen("3.in","r",stdin);
        scanf("%s",S+1); N=strlen(S+1); Q=read();
        for(int i=1;i<=N;i++){
            for(int j=0;j<26;j++) pre[i][j]=pre[i-1][j];
            pre[i][S[i]-'a']=i;
        }
        for(int i=0;i<26;i++) suf[N+1][i]=N+1;
        for(int i=N;i>=1;i--){
            for(int j=0;j<26;j++) suf[i][j]=suf[i+1][j];
            suf[i][S[i]-'a']=i;
        }
        S[0]='a';
        memset(f,-1,sizeof(f));
        for(int i=1;i<=N;i++){
            g[i]=g[pre[i-1][S[i]-'a']]^f[i-1][S[i]-'a'];
            for(int j=0;j<26;j++){
                if(f[i][j]!=-1) continue;
                f[i][j]=calc(pre[i][j]+1,i);
            }
        }memset(F,-1,sizeof(F));
        while(Q--){
            int l=read(),r=read();
            if(Solve(l,r)) printf("Alice
    ");
            else printf("Bob
    ");
        }return 0;
    }/*
    lmukitofnyzgvbprxcashwjedq
    0
    */
    G
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<climits>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=4e5+11;
    vector<int> vec[MAXN];
    int ch[MAXN][27],las=1,tot=1,TT=0,N,Q,len[MAXN],fa[MAXN],rt[MAXN],all; char S[MAXN];
    struct Segment{
        int ls[MAXN*34],rs[MAXN*34];
        void Modify(int &k,int l,int r,int ps){
            if(!k) k=++TT; if(l==r) return;
            int mid=(l+r)>>1; if(ps<=mid) Modify(ls[k],l,mid,ps); if(mid<ps) Modify(rs[k],mid+1,r,ps);
            return;
        }
        void print(int k,int l,int r){
            if(!k) return;
            if(l==r){printf("%d ",l);return;}
            int mid=(l+r)>>1; print(ls[k],l,mid),print(rs[k],mid+1,r);
        }
        int merge(int p,int q){
            if(!p||!q) return p+q;
            int u=(++TT); ls[u]=merge(ls[p],ls[q]),rs[u]=merge(rs[p],rs[q]);
            return u;
        }
        bool Query(int k,int l,int r,int x,int y){
            if(!k) return 0; if(x<=l&&r<=y) return 1;
            int mid=(l+r)>>1; bool res=0; if(x<=mid) res|=Query(ls[k],l,mid,x,y); if(mid<y) res|=Query(rs[k],mid+1,r,x,y);
            return res;
        }
        void debug(int k){print(rt[k],1,N); printf("
    ");return;}
    }T;
    void ins(int c){
        int p=las,np=las=++tot; len[np]=len[p]+1; T.Modify(rt[np],1,N,len[np]); 
        for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
        if(!p){fa[np]=1;return;}
        int q=ch[p][c]; if(len[p]+1==len[q]){fa[np]=q;return;}
        int nq=++tot; len[nq]=len[p]+1,fa[nq]=fa[q]; for(int i=0;i<27;i++) ch[nq][i]=ch[q][i];
        fa[q]=fa[np]=nq; 
        for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq; return;
    }
    void dfs(int u){for(auto v:vec[u]) dfs(v),rt[u]=T.merge(rt[u],rt[v]);}
    int L,R,LEN; char Ans[MAXN]; bool ff=1;
    void calc(int now,int len,bool f){
        if(!f){for(int i=1;i<len;i++) printf("%c",Ans[i]);printf("
    ");ff=0;return;}
        int be;
        if(!f||len>LEN) be=0; else be=S[len]-'a';
        for(int i=be;i<26;i++){
            int u=ch[now][i]; if(!u) continue;
            if(!T.Query(rt[u],1,N,L+len-1,R)) continue;
            Ans[len]=i+'a';
            calc(u,len+1,f&(i==(S[len]-'a')));
            if(!ff) return;
        }
    }
    int main(){
        //freopen("H.in","r",stdin);
        scanf("%s",S+1); N=strlen(S+1); Q=read();
        for(int i=1;i<=N;i++) ins(S[i]-'a'); 
        for(int i=2;i<=tot;i++) vec[fa[i]].pb(i);
        dfs(1); //for(int i=1;i<=tot;i++) T.debug(i);
        while(Q--){
            L=read(),R=read(); scanf("%s",S+1); LEN=strlen(S+1);
            ff=1; calc(1,1,1);
            if(ff) printf("-1
    ");
            //return 0;
        }
    }/*
    baa
    5
    1 2 ba
    2 3 a
    1 2 b
    2 3 aa
    1 3 b
    */
    H
  • 相关阅读:
    【Red Hat Linux基础】 磁盘分区详细教程
    分区间统计sql、删除重复数据
    sql 建立索引之前计算区分度
    jvm调优
    最短路径-迷宫类
    comparable and comparator 比较
    刷题之Implement strStr()、Climbing Stairs
    对线程池简单理解
    hash表系列(转)
    对于AVL树和红黑树的理解
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/14594214.html
Copyright © 2011-2022 走看看