多校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\n",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("\n");
    }
    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\n",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\n",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\n",M);
    for(int i=0;i<=n;i++)
    {
        if(s[i])
        {
           // printf("1\n");
            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\n",ans,M);
    ll ret= gao(r+M,ans,M)-gao(l-1+M,ans,M);
   // printf("%I64d\n",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\n",ans);
        }
        printf("Case #%d: %I64d\n",ca++,ans);
    }
    return 0;
}
View Code

 

 

posted on 2017-03-30 21:40  HelloWorld!--By-MJY  阅读(190)  评论(0编辑  收藏  举报

导航