zoukankan      html  css  js  c++  java
  • some problem

    CF1257F Make Them Similar

    $solution:$

    折半搜索后考虑如何维护两个数组的和,可以将 $A$ 中每个数减 $A_1$ ,$B$ 中每个数被减 $B_1$ ,$map$ 维护一下即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<vector>
    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=101;
    int lowbit(int x){return x&-x;}
    int cont(int x){int c=0;while(x) c++,x-=lowbit(x);return c;}
    int N,A[MAXN];
    vector<int> sta;
    map<vector<int> ,int> M;
    int main(){
        N=read();for(int i=1;i<=N;i++) A[i]=read();
        for(int i=0;i<(1<<15)-1;i++){
            int cur=cont(i^((A[1]>>15)));sta.clear();
            for(int j=1;j<=N;j++) sta.push_back(cont(i^(A[j]>>15))-cur);
            M[sta]=i;
        }
        int all=((1<<15)-1);
        for(int i=0;i<(1<<15)-1;i++){
            int cur=cont(i^((A[1]&all)));sta.clear();
            for(int j=1;j<=N;j++) sta.push_back(cur-cont(i^(A[j]&all)));
            if(M.count(sta)){
                printf("%d
    ",(M[sta]<<15)+i);
                return 0;
            }
        }printf("-1
    ");return 0;
    }
    View Code

    CF1257E The Contest

     $solution:$

    设 $f_{i,j}$ 表示现在在 $i$ 个数,现在在第 $j$ 段。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    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=2000001;
    int col[MAXN],f[MAXN][3],k1,k2,k3,N;
    int main(){
        k1=read(),k2=read(),k3=read();N=k1+k2+k3;
        for(int i=1;i<=k1;i++) read();
        for(int i=1;i<=k2;i++) col[read()]=1;
        for(int i=1;i<=k3;i++) col[read()]=2;
        memset(f,127/3,sizeof(f));
        f[0][0]=0;
        for(int i=1;i<=N;i++){
            for(int j=0;j<3;j++){
                for(int k=0;k<=j;k++) f[i][j]=min(f[i][j],f[i-1][k]+(col[i]!=j));
            }
        }
        int Minn=min(f[N][0],min(f[N][1],f[N][2]));
        printf("%d
    ",Minn);return 0;
    }
    View Code

    CF1268C And Reachability

    $solution:$

    设 $f_{i,j}$ 表示从 $i$ 点走到离 $i$ 最近并且 $j$ 位上是一的,可以简单递推得到。

    时间复杂度 $O(20^2cdot n)$ 。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    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=300011;
    int f[MAXN][21],g[21],n,q,A[MAXN]; 
    int main(){
        n=read(),q=read();
        for(int i=1;i<=n;i++) A[i]=read();
        for(int i=0;i<=n+1;i++) for(int j=0;j<=20;j++) f[i][j]=g[j]=n+1;
        for(int i=n;i>=1;i--){
            for(int j=0;j<=20;j++){
                if(A[i]&(1<<j)){
                    for(int k=0;k<=20;k++) f[i][k]=min(f[i][k],f[g[j]][k]);
                    f[i][j]=i;g[j]=i;
                }
            }
        }
        while(q--){
            int x=read(),y=read();bool ok=0;
            for(int i=0;i<=20;i++) if(A[y]&(1<<i)) ok|=(f[x][i]<=y);
            if(ok){printf("Shi
    ");continue;}
            printf("Fou
    ");
        }return 0;
    }/*
    5 5
    0 0 1 3 7
    1 2
    2 2
    3 5
    4 5
    1 5
    */ 
    View Code

    CF1268B Good Triple

    $solution:$

    因为 $2kleq 9$ ,所以直接 $r$ 单调性暴力处理就行。时间复杂度 $O(9n)$ 。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int 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=410001;
    int L[MAXN],N,A[MAXN];
    char str[MAXN];
    signed main(){
        scanf("%s",str+1);N=strlen(str+1);
        for(int i=1;i<=N;i++) A[i]=str[i]-'0';
        int ll=0,Ans=0;
        for(int r=1;r<=N;r++){
            for(int i=1;r-2*i>=1;i++){
                if(A[r]==A[r-i]&&A[r-i]==A[r-2*i]){ll=max(ll,r-2*i);break;}
            }
            Ans+=ll;
        }printf("%lld
    ",Ans);
    }
    View Code

    CSGRound2 逐梦者的初心

    $solution:$

    考虑将 $S$ 串翻转后1问题就变为了维护多项式系数。$bitset$ 优化即可。

    时间复杂度 $O(dfrac{m^2}{w})$

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<bitset>
    using namespace std;
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int N=1000001;
    const int MAXN=70001;
    int n,m,A[N],Ans[MAXN];
    bitset<MAXN> Bit,ve[1001],e;
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++) A[i]=read();for(int i=1;i<=n-m;i++) read();
        for(int i=1;i<=m;i++) ve[A[i]][m-i+1]=1;
        n=m;
        for(int i=1;i<=m;i++){
            int opt=read(),x=read();
            if(opt==0) Bit|=(ve[x]<<i);
            else{Bit=(Bit<<1);Bit|=(ve[x]<<1);}
            e[m+i]=1;printf("%d
    ",(Bit.flip()&e).count());
            Bit.flip();
        }
        return 0;
    }/*
    2 2
    1 2
    1 1
    1 3
    */
    View Code

    CSGRound2 开拓者的卓识

    $solution:$

    考虑每一位 $a_i$ 对答案的贡献,根据插板原理可以得到。

    $$S_{k,1,r}=sum_{i=1}^r A_icdot dbinom{i+k-2}{k-1}cdot dbinom{r-i+k-1}{k-1}\=A_icdotdfrac{(i+k-2)!}{(k-1)!cdot(i-1)!}cdotdfrac{(r-i+k-1)!}{(k-1)!cdot(r-i)!}\=A_icdotdfrac{(i+k-2)!cdot (r-i+k-1)!}{(i-1)!cdot(r-i)!}cdotdfrac{1}{(k-1)!^2}$$

    $NTT$ 优化一下即可,而阶乘的预处理可以分段打表。

    时间复杂度 $O(nlog n+n imes blo)$

    CF1225E Rock Is Push

    $solution:$

    设 $f_{i,j,0/1}$ 表示从 $(1,1)$ 走到 $(i,j)$,其中最后一步的走向是右还是下。

    则 $f_{i,j,0}=sum_{e=k}^{j-1} f_{i,e,1}$ ,可以记录前缀和得到一段区间的 $dp$ 和。

    而 $k$ 的得到可以因为实现不同,故时间复杂度为 $O(nmlog n)$ 或 $O(nm)$ 。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #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=2011;
    int n,m,f[MAXN][MAXN][2];
    /*left 0   down 1*/
    char str[MAXN];
    int A[MAXN][MAXN],S1[MAXN][MAXN],S2[MAXN][MAXN];
    int Qi(int id,int l,int r){/*col*/
        return S1[r][id]-S1[l-1][id];
    }
    int Qj(int id,int l,int r){/*row*/
        return S2[id][r]-S2[id][l-1];
    }
    int fS1[MAXN][MAXN],fS2[MAXN][MAXN];
    int Mod(int x){return ((x%mod)+mod)%mod;}
    signed main(){
    //    freopen("maker.in","r",stdin);
        n=read(),m=read();
        for(int i=1;i<=n;i++){
            scanf("%s",str+1);
            for(int j=1;j<=m;j++) A[i][j]=(str[j]=='R');
        }
        if(n==1&&m==1){printf("%lld
    ",A[1][1]^1);return 0;}
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) S1[i][j]=S1[i-1][j]+A[i][j];
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) S2[i][j]=S2[i][j-1]+A[i][j];
        f[1][1][0]=f[1][1][1]=1;fS1[1][1]=1,fS2[1][1]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(i==1&&j==1) continue;
                int l=1,r=i-1,res=i;
                while(l<=r){
                    int mid=l+r>>1;
                    if(Qi(j,mid+1,n)<=(n-i)) res=mid,r=mid-1;
                    else l=mid+1;
                }
                f[i][j][1]=fS1[i-1][j]-fS1[res-1][j];f[i][j][1]=Mod(f[i][j][1]);
                l=1,r=j-1,res=j;
                while(l<=r){
                    int mid=l+r>>1;
                    if(Qj(i,mid+1,m)<=(m-j)) res=mid,r=mid-1;
                    else l=mid+1; 
                }
                f[i][j][0]=fS2[i][j-1]-fS2[i][res-1];f[i][j][0]=Mod(f[i][j][0]);
                fS1[i][j]=fS1[i-1][j]+f[i][j][0];fS1[i][j]=Mod(fS1[i][j]);
                fS2[i][j]=fS2[i][j-1]+f[i][j][1];fS2[i][j]=Mod(fS2[i][j]);
            }
        }printf("%lld
    ",(f[n][m][0]+f[n][m][1])%mod);return 0;
    }/*3 3
    .RR
    ...
    R..
    */
    View Code

    CF1239D Catowice City

    $solution:$

    考虑类似于 $2-SAT$ 将必须选择的关系连边,$tarjan$ 后让最开始遍历的强连通分量为 $1$ ,因为 $dfs$ 的顺序易知这是正确的。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    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=1000001;
    int n,m,T,col[MAXN],sta[MAXN],num,dfn[MAXN],low[MAXN],Ans0[MAXN],Ans1[MAXN];
    vector<int> vec[MAXN];
    void Init(){
        num=0;Ans0[0]=0,Ans1[0]=0;
        for(int i=0;i<=n;i++) vec[i].clear();
        for(int i=0;i<=n;i++) col[i]=dfn[i]=low[i]=0;
    }
    void tarjan(int u){
        dfn[u]=low[u]=++num;sta[++sta[0]]=u;
        int siz=vec[u].size();
        for(int i=0;i<siz;i++){
            int v=vec[u][i];
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }else if(!col[v]) low[u]=min(low[u],low[v]);
        }
        if(dfn[u]==low[u]){
            col[u]=++col[0];
            while(sta[sta[0]]!=u){
                col[sta[sta[0]]]=col[0];
                sta[0]--;
            }sta[0]--;
        }return;
    }
    int main(){
    //    freopen("8.in","r",stdin);
        T=read();
        while(T--){
            n=read(),m=read();
            Init();
            for(int i=1;i<=m;i++){int u=read(),v=read();vec[u].push_back(v);}
            for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
            if(col[0]==1){printf("No
    ");continue;}
            for(int i=1;i<=n;i++){
                if(col[i]==1) Ans0[++Ans0[0]]=i;
                else Ans1[++Ans1[0]]=i;
            }
            printf("Yes
    %d %d
    ",Ans0[0],Ans1[0]);
            for(int i=1;i<=Ans0[0];i++) printf("%d ",Ans0[i]);printf("
    ");
            for(int i=1;i<=Ans1[0];i++) printf("%d ",Ans1[i]);printf("
    ");
        }return 0;
    }
    View Code

    CF1244F Chips

    $solution:$

    考虑若对于 $i$ 来说在 $i-1,i+1$ 有颜色相同的话,那么无论经过多少次操作都可以为本身颜色。

    否则,与其相邻的是 $01$ 段,模拟一下即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    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=4000001;
    char str[MAXN];
    int n,k,A[MAXN],B[MAXN],C[MAXN];
    void print(int opt){opt?printf("W"):printf("B");}
    int main(){
        n=read(),k=read();
        scanf("%s",str+1);
        for(int i=1;i<=n;i++) A[i]=(str[i]=='W');
        A[0]=A[n],A[n+1]=A[1];
        for(int i=1;i<=n;i++) B[i]=(A[i-1]==A[i]||A[i]==A[i+1]),B[i+n]=B[i];
        bool F=0;for(int i=1;i<=n;i++) F|=B[i];
        if(!F){for(int i=1;i<=n;i++) print(A[i]^(k&1));printf("
    ");return 0;}
        int ps=1;for(int i=1;i<=n;i++) if(B[i]) ps=i;
        for(int i=n+1;i<=2*n;i++){if(B[i]) ps=i;C[i-n]=i-ps;}
        for(int i=2*n;i>n;i--) if(B[i]) ps=i;
        for(int i=n;i>=1;i--){if(B[i]) ps=i;C[i]=min(C[i],ps-i);}
        for(int i=1;i<=n;i++){
            if(B[i]) print(A[i]);
            else print(A[i]^(min(k,C[i])&1));
        }printf("
    ");return 0;
    }
    View Code

    CF1245F Daniel and Spring Cleaning

    $solution:$

    按维容斥后做简单数位 $dp$ 即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define int 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=30;
    int T,a,b,A[MAXN],B[MAXN],len,f[MAXN][2][2];
    int dfs(int ps,int lim1,int lim2){
        if(ps==-1) return 1;
        if(f[ps][lim1][lim2]!=-1) return f[ps][lim1][lim2];
        int e1=(lim1==1)?A[ps]:1,e2=(lim2==1)?B[ps]:1,res=0;
        for(int i=0;i<=e1;i++)
            for(int j=0;j<=e2;j++){
                if(i==1&&j==1) continue;
                res+=dfs(ps-1,lim1&&(i==A[ps]),lim2&&(j==B[ps]));
        }
        return f[ps][lim1][lim2]=res;
    }    
    int calc(int x,int y){
        if(x<0||y<0) return 0;
        memset(f,-1,sizeof(f));
        len=29;
        for(int i=29;i>=0;i--) A[i]=(x&(1<<i))?1:0;
        for(int i=29;i>=0;i--) B[i]=(y&(1<<i))?1:0;
        return dfs(29,1,1);
    } 
    signed main(){
    //    freopen("4.in","r",stdin);
        T=read();
        while(T--){
            int l=read(),r=read();
            printf("%lld
    ",calc(r,r)+calc(l-1,l-1)-2*calc(l-1,r));
        }
        return 0;
    }
    View Code

    CF1245E Hyakugoku and Ladders

     $solution:$

    设 $f_{i,j}$ 表示从 $(i,j)$ 走到 $(1,1)$ 的期望步数,按题意模拟的转移即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    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 N=11;
    int M[N][N],fro[N*N]; 
    double f[N*N];
    int main(){
        for(int i=1;i<=10;i++)
            for(int j=1;j<=10;j++){
                if(i&1) M[i][j]=(i-1)*10+j;
                else M[i][j]=(i-1)*10+11-j;
            }
        double sum=0;
        f[1]=0;for(int i=2;i<=6;i++){
            f[i]=(sum+6)/(i-1);
            sum+=f[i];
        }
        for(int i=1;i<=10;i++){
            for(int j=1;j<=10;j++){int x=read();fro[M[i][j]]=M[i-x][j];}
        }
        for(int i=7;i<=100;i++){
            double s=0;
            for(int j=1;j<=6;j++) s+=min(f[i-j],f[fro[i-j]]);
            f[i]=s/6.0+1;
        }
        printf("%.10lf
    ",f[100]);return 0;
    }
    View Code

    CF1249F Maximum Weight Subset

    $solution:$

    设 $f_{i,j}$ 表示以 $i$ 号节点为根的子树下距离 $i$ 最近的点至少为 $j$ 的方案数,枚举哪个要选即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    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 N=211; 
    int n,k,f[N][N],head[N],cnt,val[N],son[N];
    struct node{
        int u,v,nex;
    }x[N<<1];
    void add(int u,int v){
        x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],head[u]=cnt++;
    }
    void dfs(int u,int fath){
        for(int i=head[u];i!=-1;i=x[i].nex){
            if(x[i].v==fath) continue;
            dfs(x[i].v,u);
        }
        son[0]=0;
        for(int i=head[u];i!=-1;i=x[i].nex){
            if(x[i].v==fath) continue;
            son[++son[0]]=x[i].v;
        }
        for(int i=0;i<=k;i++){
            if(i==0){
                f[u][0]=val[u];
                for(int j=1;j<=son[0];j++) f[u][0]+=f[son[j]][k];
                continue;
            }
            for(int j=1;j<=son[0];j++){
                int res=f[son[j]][i-1]; 
                for(int p=1;p<=son[0];p++){
                    if(j==p) continue;
                    res+=f[son[p]][max(k-i,i-1)];
                }
                f[u][i]=max(f[u][i],res);
            }
        }for(int i=k;i>=0;i--) f[u][i]=max(f[u][i],f[u][i+1]);
    }
    int main(){
        memset(head,-1,sizeof(head));
        n=read(),k=read();
        for(int i=1;i<=n;i++) val[i]=read();
        for(int i=1;i<n;i++){
            int u=read(),v=read();
            add(u,v),add(v,u);
        }dfs(1,0);
        printf("%d
    ",f[1][0]);return 0;
    }
    View Code
  • 相关阅读:
    bios设置启动方式问题
    springmvc 之 easyUI开发商城管理系统
    maven 整合 ssm 异常分析
    maven 之nexus仓库管理_私服配置
    maven 之 web.xml 头设置错误问题
    maven之jre默认配置
    springMvc异常之 For input string: "show"
    mysql参照完整性 策略设置之 on update 和 on delete
    ssm之mapper异常 Result Maps collection already contains value for com.ssj.mapper.UserMapper 和 Type interface com.ssj.mapper.UserMapper is already known to the MapperRegistry.
    HDU-2054 A==B?
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/11794120.html
Copyright © 2011-2022 走看看