多校 2009 4

A dp

吃了 (x,y)的豆子 就不能吃x-1 x+1 行 还有 (x,y-1),(x,y+1) 的豆子

求最大 果然是菜菜   第1  先想怎么求得一行的最大的   ->>>>>    就是求最大不连续的和dp[i]=max(dp[i-1],dp[i-2]+w[i]);

那么整个矩阵呢  把上面处理出来每一行最大的 求一个最大不连续的和

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>

using namespace std;

#define MAXN 200010
#define inf  1000000007
#define ll long long

int z[MAXN];
int dp[MAXN];
int sum[MAXN];

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                scanf("%d",&z[j]);
            dp[0]=0;
            dp[1]=z[1];
            int mx=dp[1];
            for(int j=2;j<=m;j++)
            {
                dp[j]=max(dp[j-2]+z[j],dp[j-1]);
                mx=max(mx,dp[j]);
            }
            sum[i]=mx;
        }
        int mx=0;
        dp[0]=0;
        dp[1]=sum[1];
        mx=dp[1];
        for(int j=2;j<=n;j++)
        {
            dp[j]=max(dp[j-2]+sum[j],dp[j-1]);
            mx=max(mx,dp[j]);
        }
        printf("%d
",mx);
    }
    return 0;
}
View Code

H

n 然后n个操作 操作有3种

0  a   插入 a

1  a   删除 a  如果a存在的话  不存在输出  No Elment! 

2  a k 查询比a大的 第k个   不存在输出     Not Find!

0   1 
只是线段树的单点更新  不多说 

那么 查询比a大第k个   我是  先查了a在第x个  然后只要在树上查第 x+k  有没有就可以了 

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>

using namespace std;

#define MAXN 100010
#define inf  1000000007
#define ll long long

struct node
{
    int l,r,w;
}tree[MAXN<<2];

int ok;
void Build(int l,int r,int a)
{
    tree[a].l=l;
    tree[a].r=r;
    tree[a].w=0;
    if(l==r)
        return ;
    int mid=(l+r)>>1;
    Build(l,mid,a<<1);
    Build(mid+1,r,a<<1|1);
}
void Update(int l,int r,int a1,int a)
{
    if(l==r)
    {
        tree[a].w=tree[a].w+1;
        return ;
    }
    int mid=(l+r)>>1;
    if(a1<=mid)
        Update(l,mid,a1,a<<1);
    else
        Update(mid+1,r,a1,a<<1|1);
    tree[a].w=tree[a<<1].w+tree[a<<1|1].w;
}
void Delete(int l,int r,int a1,int a)
{
    if(l==r)
    {
        if(tree[a].w==0)
            ok=1;
        else
            tree[a].w=tree[a].w-1;
        return ;
    }
    int mid=(l+r)>>1;
    if(a1<=mid)
        Delete(l,mid,a1,a<<1);
    else
        Delete(mid+1,r,a1,a<<1|1);
    tree[a].w=tree[a<<1].w+tree[a<<1|1].w;
}
int Ques(int l,int r,int k,int a)
{
    if(l==r)
        return l;
    int mid=(l+r)>>1;
    if(k>tree[a<<1].w)
    {
        return Ques(mid+1,r,k-tree[a<<1].w,a<<1|1);
    }
    else
    {
        return Ques(l,mid,k,a<<1);
    }
}
int Ques1(int l,int r,int a1,int b1,int a)
{
    if(a1<=l&&r<=b1)
        return tree[a].w;
    int ans=0;
    int mid=(l+r)>>1;
    if(a1<=mid)
        ans=ans+Ques1(l,mid,a1,b1,a<<1);
    if(b1>mid)
        ans=ans+Ques1(mid+1,r,a1,b1,a<<1|1);
    return ans;
}
int main()
{
    int n;
    int r=100000;
    while(scanf("%d",&n)!=EOF)
    {
        Build(1,r,1);
        while(n--)
        {
            int type;
            scanf("%d",&type);
            if(type==0)
            {
                int a;
                scanf("%d",&a);
                Update(1,r,a,1);
            }
            else if(type==1)
            {
                int a;
                scanf("%d",&a);
                ok=0;
                Delete(1,r,a,1);
               // printf("%d
",ok);
                if(ok==1)
                    printf("No Elment!
");
            }
            else
            {
                int a,k;
                ok=0;
                scanf("%d%d",&a,&k);
                int c=Ques1(1,r,1,a,1);
                k=k+c;
                if(k>tree[1].w)
                {
                    printf("Not Find!
");
                    continue;
                }
                int ans=Ques(1,r,k,1);
                printf("%d
",ans);
            }
        }
    }
    return 0;
}
View Code

 B

n然后 n个串

m然后m个串  问上面有多少个串包括下面这个串   输出m个数字

n个串建字典树    abab   那么就是   abab   bab  ab b  但是不能重复计数  那么 加上个标记就行了

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<stdlib.h>

using namespace std;

#define MAXN 100010
#define inf  1000000007
#define ll long long

char s[25];
struct node
{
    int cnt,id;
    struct node *next[27];
    void cl()
    {
        memset(next,0,sizeof(next));
        cnt=1;
    }
};
int ok;
void Insert(char *s,struct node *p,int cou)
{
    while(*s)
    {
        int a=*s-'a';
        if(p->next[a]==0)
        {
            p->next[a]=(struct node *)malloc(sizeof(struct node));
            (p->next[a])->cl();
            (p->next[a])->id=cou;
        }
        p=p->next[a];
        if(p->id!=cou)
        {
            (p->cnt)++;
            p->id=cou;
        }
        s++;
    }
}

int Ques(char *s,struct node *p)
{
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int a=s[i]-'a';
        if(p->next[a])
            p=p->next[a];
        else
            return 0;
    }
    return p->cnt;
}

int main()
{
    int n,m;
    scanf("%d",&n);
    struct node * root;
    root=(struct node *)malloc(sizeof(struct node));
    root->cl();
    int cou=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        ok=0;
        int len=strlen(s);
        for(int j=0;j<len;j++)
        {
            Insert(s+j,root,cou);
            ok=1;
        }
        cou++;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int ans=0;
        scanf("%s",s);
        ans=Ques(s,root);
        printf("%d
",ans);
    }
    return 0;
}
View Code

 C

给你一个2进制字符串a  然后一个数b  要求在这个字符串上补0或者1  使得b能整除a 求长度最小  字典序最小  不可能输出impossibl
显然是可能的 至少可以在最后加上b   然后 最多就是2^20次方 直接跑的  然后求一下列举的b的倍数是不是包含a就可以了    a=0注意下  

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
#include<queue>
#include<stdlib.h>

using namespace std;

#define MAXN 100010
#define inf  1000000007
#define ll long long

char z[35];
char s[35];

int main()
{
    while(scanf("%s",z)!=EOF)
    {
        int a;
        scanf("%d",&a);
        int b=0;
        int len=strlen(z);
        for(int i=0;i<len;i++)
            b=b*2+z[i]-'0';
        if(b%a==0)
        {
            printf("%d
",b);
            continue;
        }
        for(int i=1;;i++)
        {
            int c=a*i;
                int cnt=0;
                int d=c;
                while(d)
                {
                    s[cnt++]=d%2+'0';
                    d=d/2;
                }
                for(int j=0;j<(cnt+1)/2;j++)
                    swap(s[j],s[cnt-j-1]);
                int c1,c2;
                s[cnt]='';
                for(c1=c2=0;c1<cnt&&c2<len;)
                {
                    if(s[c1]==z[c2])
                    {
                        c1++;
                        c2++;
                    }
                    else
                    {
                        c1++;
                    }
                }
                if(c2==len)
                {
                    printf("%s
",s);
                    break;
                }

        }
    }
    return 0;
}
View Code

 G题意至今未读懂

原文地址:https://www.cnblogs.com/cherryMJY/p/6893249.html