CF Round706简要题解

ABCD

A:贪心 B:讨论 C:贪心 D:讨论

#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=1e3+11;
int T,N,K; char S[MAXN];
int main(){
    T=read(); while(T--){
        N=read(),K=read(); scanf("%s",S+1); bool ff=1;
        for(int i=1;i<=K;i++) if(S[i]!=S[N-i+1]){ff=0;break;}
        if(!ff){printf("NO\n");continue;}
        int L=K+1,R=N-K;
        if(L>R){printf("NO\n");continue;}
        printf("YES\n");
    }return 0;
}
View Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#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;
map<int,int> Ma; int T,N,K,A[MAXN];
int main(){
    //freopen("6.in","r",stdin);
    T=read(); while(T--){
        int Maxn=0;
        N=read(),K=read(); Ma.clear(); for(int i=1;i<=N;i++) A[i]=read(),Maxn=max(Maxn,A[i]),Ma[A[i]]=1;
        if(!K){printf("%d\n",N);continue;}
        int mex=0; while(Ma[mex]) ++mex;
        if(Maxn+1==mex){printf("%d\n",N+K);continue;}
        int s=(mex+Maxn+1)/2; if(Ma[s]){printf("%d\n",N);continue;}
        printf("%d\n",N+1); 
    }return 0;
}
View Code
#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
#include<cmath>
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;
double XX[MAXN],YY[MAXN];int N,T,tot1,tot2;
int main(){
    //freopen("1.in","r",stdin);
    T=read(); while(T--){
         tot1=0,tot2=0;
        N=read(); for(int i=1;i<=N*2;i++){
            double x,y; scanf("%lf%lf",&x,&y);x=abs(x),y=abs(y);
            if(!x) XX[++tot1]=y; if(!y) YY[++tot2]=x;
        }
        sort(XX+1,XX+N+1),sort(YY+1,YY+N+1);
        double res=0;
        for(int i=1;i<=N;i++) res+=sqrt(XX[i]*XX[i]+YY[i]*YY[i]);
        printf("%.10lf\n",res);
    }return 0;
}
View Code
#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;
int UL[MAXN],UR[MAXN],DL[MAXN],DR[MAXN],N,U[MAXN],D[MAXN],A[MAXN];
int pre[MAXN],suf[MAXN];
int main(){
    //freopen("maker.in","r",stdin);
    N=read(); for(int i=1;i<=N;i++) A[i]=read();
    UL[1]=DL[1]=1; for(int i=2;i<=N;i++){
        if(A[i-1]<A[i]) DL[i]=DL[i-1],UL[i]=i;
        else UL[i]=UL[i-1],DL[i]=i;
    }
    UR[N]=DR[N]=N; for(int i=N-1;i>=1;i--){
        if(A[i]<A[i+1]) UR[i]=UR[i+1],DR[i]=i;
        else DR[i]=DR[i+1],UR[i]=i;
    }
    for(int i=1;i<=N;i++) U[i]=max(i-UL[i]+1,UR[i]-i+1); for(int i=1;i<=N;i++) D[i]=max(i-DL[i]+1,DR[i]-i+1);    
    for(int i=1;i<=N;i++) pre[i]=max(pre[i-1],U[i]); for(int i=N;i>=1;i--) suf[i]=max(suf[i+1],U[i]);
 
    int Ans=0;
    for(int i=2;i<N;i++){
        if(A[i-1]<A[i]&&A[i]>A[i+1]){
            if(i-DL[i]+1!=DR[i]-i+1) continue;
            int LL=DL[i],RR=DR[i];
            int res1=max(pre[LL-1],LL-UL[LL]+1),res2=max(suf[RR+1],UR[RR]-RR+1);
            if(i-LL+1>max(res1,res2)&&((i-LL+1)&1)){
                cerr<<i<<endl;
                Ans++;
            }
        }
    }printf("%d\n",Ans); return 0;
}/*s
 
7
2 5 7 3 1 4 6
 
*/
View Code

E

由于题目保证两个 X 之间没有边角连接,那么 X 肯定在 $3\cdot 3$ 正方形的中间,考虑列对 $\bmod 3$ 分类,将 $1,4,7,10,...,3k+1$ 列全变为 X ,在列之间随意打通一个。

注意当 $m\bmod 3$ 时需要特判。

#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=511;
int T,N,M; char str[MAXN][MAXN];
int main(){
    //freopen("3.in","r",stdin);
    T=read(); while(T--){
        N=read(),M=read(); for(int i=1;i<=N;i++) scanf("%s",str[i]+1);
        for(int i=1+((M%3)==0);i<=M;i+=3){
            bool ff=1;
            for(int j=1;j<=N;j++) str[j][i]='X';
            for(int j=1;j<=N;j++) if((str[j][i+1]=='X'||str[j][i+2]=='X')&&ff){str[j][i+1]=str[j][i+2]='X';ff=0;}
            if(ff){str[1][i+1]=str[1][i+2]='X';}
        }
        for(int i=1;i<=N;i++) {for(int j=1;j<=M;j++) printf("%c",str[i][j]);printf("\n");}
        //printf("============\n");
    }
}
View Code

F

枚举 $S,T$ 。

如果 $S\rightarrow T$ 之间的最短路不止一条那么答案肯定为 $0$ ,证明可以考虑两条路径最后相交的点设为 $x$ ,那么存在两条不交的环,显然从 $T$ 走到第二个路径上最后一个点必定不为最短路。

那么可以将 $S\rightarrow T$ 之间的最短路径摘出来,看成一个大点。定义二元组 $(u,v)$ 表示 $i$ 号点到 $S,T$ 的最短路,那么若两个点在 $dfs$ 树上存在父亲/儿子关系,必然 $u'+1=u,v'+1=v$ 。

可以发现这是一个充要条件。

枚举答案即可。时间复杂度 $O(mn^2)$ 。

#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 998244353
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=611;
int N,M,dis[MAXN][MAXN],d[MAXN],vis[MAXN]; vector<int> vec[MAXN]; queue<int> que;
void Get(int u){
    dis[u][u]=0; que.push(u); while(!que.empty()){
        int xx=que.front(); que.pop();
        for(auto v:vec[xx]) if(dis[u][v]>dis[u][xx]+1){dis[u][v]=dis[u][xx]+1;que.push(v);}
    }return;
}
int Query(int S,int T){
    int res=1,cnt=0;  memset(vis,0,sizeof(vis));
    for(int u=1;u<=N;u++){
        if(dis[S][u]+dis[u][T]==dis[S][T]){
            if(vis[dis[S][u]]) return 0;
            vis[dis[S][u]]=1;
            d[u]=1;continue;
        }
        d[u]=0;
        for(auto v:vec[u]) if(dis[S][v]+1==dis[S][u]&&dis[T][v]+1==dis[T][u]) ++d[u]; 
    }
    for(int i=1;i<=N;i++) res*=d[i],res%=mod; return res;
}
signed main(){
    //freopen("4.in","r",stdin);
    N=read(),M=read(); memset(dis,127/3,sizeof(dis));
    for(int i=1;i<=M;i++){int u=read(),v=read();vec[u].pb(v),vec[v].pb(u);}
    for(int i=1;i<=N;i++) Get(i);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++) printf("%lld ",Query(i,j));printf("\n");
    }return 0;
}/*
4 4
1 2
2 3
3 4
1 4
*/
View Code

G

显然最后被取光的是数量小的,不妨将其颜色设为 $A$ 。

那么取的序列一定是 $ABABAB.../BABABA$ ,对于 $BABABA...$ 的情况我们可以将第一个 $B$ 暴力就能变成第一个情况。

注意到无论如何改变 $A$ 的位置答案均是相同的,因为考虑交换两个相邻的 $A$ ,若他们不在同一个极大 $A$ 联通块中显然交换无影响,若在同一极大联通块依然是对下一个联通块产生贡献,在结果上是相同的。

那么我们将相同的 $A$ 放在一起,维护当前剩余 $A$ 的数量即可。

#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
#define LL long long
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=5e6+11;
const int MAXM=2e5+11;
int col[MAXN],ret,seed,base,A[MAXN],B[MAXN],N,M,p[MAXM],k[MAXM],b[MAXM],w[MAXM];
int rnd(){
    ret=seed,seed=(LL)((LL)seed*base+233)%mod; return ret;
}
signed main(){
    //freopen("A.in","r",stdin);
    N=read(),M=read(); for(int i=1;i<=M;i++) p[i]=read(),k[i]=read(),b[i]=read(),w[i]=read();
    p[0]=0; for(int i=1;i<=M;i++){seed=b[i],base=w[i];for(int j=p[i-1]+1;j<=p[i];j++) col[j]=(rnd()%2)+1,B[j]=A[j]=(rnd()%k[i])+1;}
    int res1=0,res2=0;
    for(int i=1;i<=N;i++) if(col[i]==1) res1+=A[i];else res2+=A[i];
    int ps=0; if(res1!=res2){
        if(res1<res2) ps=1; else ps=2;
    }else ps=col[1];
    int be=0,res=(ps==1)?res1:res2;
    //for(int i=1;i<=N;i++) cerr<<col[i]<<" ";cerr<<endl;
    //for(int i=1;i<=N;i++) cerr<<A[i]<<" ";cerr<<endl;
    int cnt=0; 
    if(col[1]==ps) be=1;
    else {A[1]--; for(int i=1;i<=N;i++) if(col[i]==ps){be=i;break;}}
    //for(int i=1;i<=N;i++) cerr<<A[i]<<" ";cerr<<endl;
    while(res||cnt){
        if(A[be]){
            if(col[be]==ps){cnt+=A[be];res-=A[be];A[be]=0;}
            else{
                int w=min(A[be],cnt); A[be]-=w;
                cnt-=w;
            }
        } be++; if(be==N+1) be=1;
    }
    LL Ans=1;
    //for(int i=1;i<=N;i++) cerr<<B[i]-A[i]<<" ";cerr<<"\n";
    for(int i=1;i<=N;i++) Ans*=(LL)((LL)((B[i]-A[i])^(LL)(i*i))+1)%mod,Ans%=mod;
    printf("%lld\n",Ans); return 0;
}
View Code

H

咕咕咕 

posted @ 2021-03-11 15:08  siruiyang_sry  阅读(86)  评论(0编辑  收藏  举报