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\}$ ,那么我们将 $i\bmod k-1$ 相同的看成一族同一处理那么问题变成求 $\sum_{1\leq 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\n",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\n",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\n",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\n",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\n",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\n",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\n");
        else printf("Bob\n");
    }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("\n");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("\n");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\n");
        //return 0;
    }
}/*
baa
5
1 2 ba
2 3 a
1 2 b
2 3 aa
1 3 b
*/
H

 

posted @ 2021-03-29 20:56  siruiyang_sry  阅读(100)  评论(0编辑  收藏  举报