• 多校4


    5道 

    K HDU 5774

    直接贴过来模拟

    出现的次数

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  200010
    #define inf  2000000007
    #define mod 1000000007
    char z[150][35]={"Cleveland Cavaliers",
    "Golden State Warriors",
    "San Antonio Spurs",
    "Miami Heat",
    "Miami Heat",
    "Dallas Mavericks",
    "L.A. Lakers",
    "L.A. Lakers",
    "Boston Celtics",
    "San Antonio Spurs",
    "Miami Heat",
    "San Antonio Spurs",
    "Detroit Pistons",
    "San Antonio Spurs",
    "L.A. Lakers",
    "L.A. Lakers",
    "L.A. Lakers",
    "San Antonio Spurs",
    "Chicago Bulls",
    "Chicago Bulls",
    "Chicago Bulls",
    "Houston Rockets",
    "Houston Rockets",
    "Chicago Bulls",
    "Chicago Bulls",
    "Chicago Bulls",
    "Detroit Pistons",
    "Detroit Pistons",
    "L.A. Lakers",
    "L.A. Lakers",
    "Boston Celtics",
    "L.A. Lakers",
    "Boston Celtics",
    "Philadelphia 76ers",
    "L.A. Lakers",
    "Boston Celtics",
    "L.A. Lakers",
    "Seattle Sonics",
    "Washington Bullets",
    "Portland Trail Blazers",
    "Boston Celtics",
    "Golden State Warriors",
    "Boston Celtics",
    "New York Knicks",
    "L.A. Lakers",
    "Milwaukee Bucks",
    "New York Knicks",
    "Boston Celtics",
    "Boston Celtics",
    "Philadelphia 76ers",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "Boston Celtics",
    "St. Louis Hawks",
    "Boston Celtics",
    "Philadelphia Warriors",
    "Syracuse Nats",
    "Minneapolis Lakers",
    "Minneapolis Lakers",
    "Minneapolis Lakers",
    "Rochester Royals",
    "Minneapolis Lakers",
    "Minneapolis Lakers",
    "Baltimore Bullets",
    "Philadelphia Warriors" };
    
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        getchar();
        ca=1;
    
        while(t--)
        {
            char  s[35];
            gets(s);
            int cnt=0;
            for(int i=0;i<70;i++)
                if(strcmp(z[i],s)==0)
                    cnt++;
            printf("Case #%d: %d
    ",ca++,cnt);
        }
        return 0;
    }
    View Code

    L t组样例 n n个数 HDU 5775

    输出  i  出现的最左边的位子与最右边的位子的距离

    显然 大 i 只能往右走  小的往左 最左边的位子就是 当前位子 或者i    最右边就是查询右边有多少个数比他小或者当前位子

    多少个比他小  线段树维护一下 

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  200010
    #define inf  2000000007
    #define mod 1000000007
    int z[MAXN];
    struct node
    {
        int l,r,w;
    }tree[MAXN<<2];
    int l1[MAXN],r1[MAXN];
    
    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++;
            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;
    }
    int Ques(int l,int r,int a1,int b1,int a)
    {
        if(a1<=l&&r<=b1)
            return tree[a].w;
        int mid=(l+r)>>1;
        int ans=0;
        if(a1<=mid)
            ans+=Ques(l,mid,a1,b1,a<<1);
        if(b1>mid)
            ans+=Ques(mid+1,r,a1,b1,a<<1|1);
        return ans;
    }
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        ca=1;
    
        while(t--)
        {
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&z[i]);
            Build(1,n,1);
    
            for(int i=n;i>=1;i--)
            {
                l1[z[i]]=min(i,z[i]);
                int a;
                if(z[i]==1)
                    a=0;
                else
                    a=Ques(1,n,1,z[i]-1,1);
                r1[z[i]]=max(z[i],i+a);
                Update(1,n,z[i],1);
            }
            printf("Case #%d:",ca++);
            for(int i=1;i<=n;i++)
                printf(" %d",r1[i]-l1[i]);
            printf("
    ");
        }
        return 0;
    }
    View Code

    A HDU 5763

    t组样例  2个字符串

    求第一串有多少个意思 如果第二个串出现的话就可以有2种意思

    先kmp 处理一下有没有出现  然后dp

    dp[i]=max(dp[i],dp[i-1]);

    如果出现 dp[i]=max(dp[i],dp[i-1]+dp[i-len2]+1)  %mod;

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  200010
    #define inf  2000000007
    #define mod 1000000007
    char s1[MAXN],s2[MAXN];
    ll dp[MAXN];
    void kmp(char x[],int m,int next[])
    {
        int i,j;
        j=next[0]=-1;
        i=0;
        while(i<m)
        {
            while(j!=-1&&x[i]!=x[j])
                j=next[j];
            next[++i]=++j;
        }
    }
    int nex[MAXN];
    bool vis[MAXN];
    
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        ca=1;
    
        while(t--)
        {
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
            memset(nex,-1,sizeof(nex));
            scanf("%s%s",s1,s2);
            int len2=strlen(s2);
            int len1=strlen(s1);
            kmp(s2,len2,nex);
            int i,j;
            i=j=0;
            int ans=0;
            while(i<len1)
            {
                while(j!=-1&&s1[i]!=s2[j])
                    j=nex[j];
                i++;
                j++;
                if(j>=len2)
                {
                    vis[i-1]=1;
                    j=nex[j];
                }
            }
            for(int i=0;i<len2;i++)
                dp[i]=vis[i];
    
            for(int i=len2;i<len1;i++)
            {
                if(vis[i])
                    dp[i]=(dp[i-1]+dp[i-len2]+1)%mod;
                else
                    dp[i]=dp[i-1];
            }
    
            printf("Case #%d: %I64d
    ",ca++,(dp[len1-1]+1)%mod);
        }
        return 0;
    }
    View Code

    J HDU 5773

    t 组样例

    n n 个数

    求出最长上升子序列 0可以变成任何整数 严格上升

    前面有多少个0 这个数可以减少多少 然后求最长上升子序列  nlogn

    加上0的个数              有点不理解的  不过好像也很对

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  200010
    #define inf  2000000007
    #define mod 1000000007
    int z[MAXN];
    int dp[MAXN];
    int sum[MAXN];
    bool vis[MAXN];
    
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        ca=1;
    
        while(t--)
        {
            int n;
            scanf("%d",&n);
            memset(dp,0,sizeof(dp));
            memset(sum,0,sizeof(sum));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&z[i]);
                if(z[i]==0)
                {
                     sum[i]=sum[i-1]+1;
                     vis[i]=1;
                }
                else
                    sum[i]=sum[i-1];
                z[i]=z[i]-sum[i];
            }
            int ans=sum[n];
            dp[0]=-inf;
            int cnt=0;
            for(int i=1;i<=n;i++)
            {
                if(vis[i]==1)
                    continue;
                if(z[i]>dp[cnt])
                    dp[++cnt]=z[i];
                else
                {
                    int ind=lower_bound(dp,dp+cnt+1,z[i])-dp;
                    dp[ind]=z[i];
                }
            }
            ans +=cnt;
            printf("Case #%d: %d
    ",ca++,ans);
    
    
        }
        return 0;
    }
    View Code

    E HDU 5768

    数学依旧难

    t t组样例  n 个条件   l  r

    求满足 l ~r  能被7整除  然后满足条件的

    pi  ai   不能是%pi = ai

    这B 显然是CRT然而并不会  其实CRT都忘记了  逆原都只会快速幂的了 

    GG

    0~1<<n 

    容斥   奇加偶减   其实是要反一下的的

    快速加法 然后求的结果也不是 r/ans的  要换个式子

    #include<stdio.h>
    #include<algorithm>
    #include<stdlib.h>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iterator>
    #include<stack>
    
    using namespace std;
    
    #define ll   __int64
    #define MAXN  200010
    #define inf  2000000007
    #define mod 1000000007
    
    int z[MAXN],m[MAXN],s[MAXN];
    int n;
    ll Quick(ll a,ll b,ll c) //快速幂
    {
        ll ans=1;
        a=a%c;
        while(b>0)
        {
            if(b&1)
                ans = (ans *a)%c;
            b>>=1;
            a=(a*a)%c;
        }
        return ans;
    }
    ll gao(ll a,ll r,ll p)  //求结果
    {
        return (a-r)/p;
    }
    ll add(ll a,ll b,ll c) //快速加法
    {
        ll ans=0;
        a=a%c;
        while(b>0)
        {
            if(b&1)
                ans = (ans +a)%c;
            b>>=1;
            a=(a+a)%c;
        }
        return ans;
    }
    
    ll CRT(ll l,ll r)//z中国剩余定理
    {
        ll M=1;
        ll ans=0;
        for(int i=0;i<=n;i++)
        if(s[i])
            M*=z[i];
        //printf("%I64d
    ",M);
        for(int i=0;i<=n;i++)
        {
            if(s[i])
            {
               // printf("1
    ");
                ll ni;
                ll Mi=M/z[i];
                ni = Quick(Mi,z[i]-2,z[i]);
                ni=(ni%z[i]+z[i])%z[i];
                ans =(ans+add(add(Mi,ni,M),m[i],M)%M+M)%M;
            }
        }
    
        if(ans<0)
            ans += M;
        //printf("%I64d %I64d
    ",ans,M);
        ll ret= gao(r+M,ans,M)-gao(l-1+M,ans,M);
       // printf("%I64d
    ",ret);
        return ret;
    }
    
    int main()
    {
        int t,ca;
        scanf("%d",&t);
        ca=1;
    
        while(t--)
        {
            ll l,r;
            scanf("%d%I64d%I64d",&n,&l,&r);
            for(int i=0;i<n;i++)
                scanf("%d%d",&z[i],&m[i]);
            memset(s,0,sizeof(s));
            s[n]=1;
            z[n]=7;
            m[n]=0;
            int len=1<<n;
            ll ans=0;
    
            for(int i=0;i<len;i++)
            {
                int a=i;
                int k=0;
                for(int j=0;j<n;j++)
                {
                    s[j]=0;
                    if((1<<j)&a)
                        s[j]=1;
                    k=k+s[j];
    
                }
                k=k & 1 ?-1:1;
    
                ans += 1ll *k *CRT(l,r);
                //printf("%I64d
    ",ans);
            }
            printf("Case #%d: %I64d
    ",ca++,ans);
        }
        return 0;
    }
    View Code

     

  • 相关阅读:
    day02_05.除数与被除数
    day02_04.算算多少人
    day02_03.五个数字一行输出
    day02_02.能被3整除的个位数为6的数
    day02_01.能被3整除的数
    day05_10 作业
    day05_09 列表内置方法
    day05_08 列表讲解、切片、内置方法
    day05_07 标志位讲解
    day05_06 continue语句、while循环
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6648704.html
Copyright © 2020-2023  润新知