• Codeforces Round #556 (Div. 1)


    A Prefix Sum Primes 

    显然,除了 2 以外的质数都是奇数,所以最优的排布方式应该是 21222222.... 然后 2 不够的时候再放 1  

    code:

    #include <bits/stdc++.h> 
    #define N 200009   
    #define setIO(s) freopen(s".in","r",stdin)   
    using namespace std; 
    int vis[N],prime[N],cnt;  
    void init() 
    { 
        int i,j; 
        for(i=2;i<N;++i) 
        {
            if(!vis[i]) prime[++cnt]=i;  
            for(j=1;j<=cnt&&i*prime[j]<N;++j) 
            {
                vis[i*prime[j]]=1;  
                if(i%prime[j]==0) 
                    break;  
            }
        }
    }
    int main() 
    { 
        // setIO("input");   
        // init();  
        int n,a1=0,a2=0,i,j;   
        scanf("%d",&n);   
        for(i=1;i<=n;++i) 
        {
            int x; 
            scanf("%d",&x);  
            if(x==1) 
                ++a1;  
            else 
                ++a2;  
        }     
        if(!a2)
        { 
            for(i=1;i<=n;++i) printf("%d ",1);   
        }
        else 
        {
            printf("%d ",2),--a2;     
            if(a1) printf("%d ",1),--a1;    
            while(a2) printf("%d ",2),--a2;   
            while(a1) printf("%d ",1),--a1;  
        }
        return 0;   
    }
    

      

    B  Three Religions

    有一个朴素的dp : $f[i][a][b][c]$ 表示母串匹配到 $i$,三个子串分别匹配了长度为 $a,b,c$   

    然后我们发现我们可以将状态改为 $f[a][b][c]$ 表示三个子串匹配到 $a,b,c$ 时母串的最小位置,然后开一个 $next[pos][c]$ 来转移.   

    code:

    #include <bits/stdc++.h>  
    #define ll long long 
    #define MAX 100300   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;
    int n,Q;       
    char s[MAX],a[4][MAX];  
    int nxt[MAX][26],lst[26],len[4],f[255][255][255];    
    void dp(int x,int y,int z) 
    {
        if(!(x|y|z)) 
            return;   
        f[x][y][z]=n+1;    
        if(x&&f[x-1][y][z]<=n)  
            f[x][y][z]=min(f[x][y][z],nxt[f[x-1][y][z]][a[1][x]-97]);     
        if(y&&f[x][y-1][z]<=n)   
            f[x][y][z]=min(f[x][y][z],nxt[f[x][y-1][z]][a[2][y]-97]);     
        if(z&&f[x][y][z-1]<=n)   
            f[x][y][z]=min(f[x][y][z],nxt[f[x][y][z-1]][a[3][z]-97]);   
    }
    int main() 
    { 
        // setIO("input");  
        int i,j;  
        scanf("%d%d%s",&n,&Q,s+1);     
        for(i=0;i<26;++i) lst[i]=n+1;     
        for(i=n;i>=0;--i) 
        {
            for(j=0;j<26;++j) nxt[i][j]=lst[j];     
            if(i) lst[s[i]-97]=i; 
        }
        while(Q--) 
        { 
            int x;  
            char ch[2],ss[2];   
            scanf("%s%d",ch,&x);    
            if(ch[0]=='+') 
            {     
                scanf("%s",ss);  
                a[x][++len[x]]=ss[0];      
                if(x==1) 
                {
                    for(i=0;i<=len[2];++i) 
                        for(j=0;j<=len[3];++j)   
                            dp(len[1],i,j);   
                }
                if(x==2) 
                {
                    for(i=0;i<=len[1];++i) 
                        for(j=0;j<=len[3];++j)   
                            dp(i,len[2],j);   
                }
                if(x==3) 
                {
                    for(i=0;i<=len[1];++i) 
                        for(j=0;j<=len[2];++j)   
                            dp(i,j,len[3]);   
                }
            }    
            else 
                --len[x];     
            if(f[len[1]][len[2]][len[3]]<=n)    
                printf("YES
    ");   
            else 
                printf("NO
    ");   
        }
        return 0;
    }
    

      

    C Tree Generator™   

    将左括号看成 $1$,右括号看成 $-1$.  

    我们发现答案是最大的一个连续子段的后半部分减去前半部分的值.  

    然后这个东西用线段树维护就行. 

    code: 

    #include <bits/stdc++.h>  
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;
    #define N 200400    
    #define lson (now<<1) 
    #define rson (now<<1|1)    
    int n,Q;   
    char str[N];    
    struct node {
        int pre[2],suf[2],ans,sum,tot;  
    }s[N<<2],L,R;         
    node operator+(node a,node b) 
    {
        node c;     
        c.pre[0]=max(a.pre[0],a.sum+b.pre[0]);      
        c.pre[1]=max(a.pre[1],max(a.tot+b.pre[0],-a.sum+b.pre[1]));    
        c.suf[0]=max(b.suf[0],-b.sum+a.suf[0]);     
        c.suf[1]=max(b.suf[1],max(b.tot+a.suf[0],b.sum+a.suf[1]));    
        c.sum=a.sum+b.sum;      
        c.tot=max(a.tot+b.sum,-a.sum+b.tot);   
        c.ans=max(max(a.ans,b.ans),max(a.suf[0]+b.pre[1],a.suf[1]+b.pre[0]));   
        return c;   
    }    
    void modify(int now,int l,int r,int p) 
    {
        if(l==r) 
        {
            s[now]=(str[p]=='(')?L:R;   
            return;   
        }
        int mid=(l+r)>>1;  
        if(p<=mid)  
            modify(lson,l,mid,p);     
        else 
            modify(rson,mid+1,r,p);     
        s[now]=s[lson]+s[rson];         
    }
    int main() 
    {   
        // setIO("input");  
        int i,j;  
        L=(node){1,1,0,1,1,1,1};   
        R=(node){0,1,1,1,1,-1,1};    
        scanf("%d",&n);     
        n=((n-1)<<1);              
        scanf("%d",&Q);     
        scanf("%s",str+1);    
        for(i=1;i<=n;++i) modify(1,1,n,i);     
        printf("%d
    ",s[1].ans);    
        while(Q--) 
        {
            int x,y;     
            scanf("%d%d",&x,&y);    
            swap(str[x],str[y]);       
            modify(1,1,n,x),modify(1,1,n,y);   
            printf("%d
    ",s[1].ans);  
        }
        return 0;
    }
    

      

  • 相关阅读:
    Nginx编译安装
    Docker下mysql容器开启binlog日志(保留7天)
    podman
    error: audit:backlog limit exceeded
    64位win2003/win2008系统IIS6.0/7.5配置PHP的方法
    iis7.5安装配置php环境详细清晰教程,三步实现【图文】
    Windows下IIS+PHP 5.2的安装与配置
    无线路由MAC地址过滤安全可靠性讨论
    debian flam3 源码
    debian flam3 依赖文件
  • 原文地址:https://www.cnblogs.com/guangheli/p/12383164.html
Copyright © 2020-2023  润新知