2016 Multi-University Training Contest 6

HDU【5793】——A Boring Question

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

There are an equation.

0k1,k2,,kmn1jm(kj+1kj)(mod1000000007)=?

We define that (kj+1kj)=kj+1!kj!(kj+1kj)! . And (kj+1kj)=0 while kj+1<kj .

You have to get the answer for each n and m that given to you.

For example,if n=1,m=3,

When k1=0,k2=0,k3=0,(k2k1)(k3k2)=1 ;
When k1=0,k2=1,k3=0,(k2k1)(k3k2)=0;
When k1=1,k2=0,k3=0,(k2k1)(k3k2)=0;
When k1=1,k2=1,k3=0,(k2k1)(k3k2)=0;
When k1=0,k2=0,k3=1,(k2k1)(k3k2)=1;
When k1=0,k2=1,k3=1,(k2k1)(k3k2)=1;
When k1=1,k2=0,k3=1,(k2k1)(k3k2)=0;
When k1=1,k2=1,k3=1,(k2k1)(k3k2)=1.

So the answer is 4.

Input

The first line of the input contains the only integer T,(1≤T≤10000)
Then T lines follow,the i-th line contains two integers n,m,(0≤n≤ 109 ,2≤m≤ 109 )

Output

For each n and m,output the answer in a single line.

Sample Input

2
1 2
2 3

Sample Output

3
13

赛场上队友打表找出的

0k1,k2,kmn1j<m(kj+1kj)

=0k1k2kmn1j<m(kj+1kj)

=km=0nkm1=0kmk1=0k21j<m(kj+1kj)

=km=0n(kmkm1)km1=0km(km1km2)k1=0k2(k2k1)

=km=0n(kmkm1)km1=0km(km1km2)k1=0k2(k2k1)

=km=0n(kmkm1)km1=0km(km1km2)k2=0k3(k3k2)2k2

=km=0nmkm

=mn+11m1

题解解释

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const LL Mod = 1000000007;

LL pow(LL n,LL m)
{
    LL ans = 1;

    while(m)
    {
        if(m %2 )
        {
            ans = (ans*n)%Mod;
        }

        n = (n*n)%Mod;

        m>>=1;
    }

    return ans;
}

int main()
{
    int T;

    LL n,m;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%lld %lld",&n,&m);

        LL ans = pow(m,n+1);

        ans = ((ans-1)%Mod+Mod)%Mod;

        LL ant = pow(m-1,Mod-2);

        ans = (ans*ant)%Mod;

        printf("%lld\n",ans);
    }
    return 0;
}

HDU【5794】——A Simple Chess

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

There is a n×m board, a chess want to go to the position
(n,m) from the position (1,1).
The chess is able to go to position (x2,y2) from the position (x1,y1) , only and if only x1,y1,x2,y2 is satisfied that (x2x1)2+(y2y1)2=5,x2>x1,y2>y1 .
Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle.
I want you to tell me, There are how may ways the chess can achieve its goal.

Input

The input consists of multiple test cases.
For each test case:
The first line is three integers, n,m,r,(1≤n,m≤10 18 ,0≤r≤100), denoting the height of the board, the weight of the board, and the number of the obstacles on the board.
Then follow r lines, each lines have two integers, x,y(1≤x≤n,1≤y≤m), denoting the position of the obstacles. please note there aren’t never a obstacles at position (1,1).

Output

For each test case,output a single line “Case #x: y”, where x is the case number, starting from 1. And y is the answer after module 110119.

Sample Input

1 1 0
3 3 0
4 4 1
2 1
4 4 1
3 2
7 10 2
1 2
7 1

Sample Output

Case #1: 1
Case #2: 0
Case #3: 2
Case #4: 1
Case #5: 5

Author

UESTC

题意:给你棋盘的大小和一些不能走的点,问从起点到终点有多少种走法(马的走法)?n和m都比较的大,所以要用Lucas进行处理,我们定义dp[i]为从起点走到i点不经过不能走的点的方案数,那么我们可以用总的方案数减去不合法的方案数就是符合的方案数。dp[i] = dp[i]-dp[j] × < j , i> 表示总的方案数减去从起点到j点合法的方案数与j点到i点任意走的方案数。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int Mod = 110119;

const int Max = 120000;

LL fac[Max],inv[Max],facinv[Max];

typedef struct node
{
    LL x,y;

    node(){}

    node(LL _x,LL _y):x(_x),y(_y){}

    bool operator < (const node &a)const
    {
        return x == a.x ? y<a.y:x<a.x;
    }

    node operator - (const node &a) const
    {
        return node(x-a.x,y-a.y);
    }
}Point;

Point p[110];

void Init()
{
    fac[0] = inv[0] = facinv[0] = 1;

    fac[1] = inv[1] = facinv[1] =1;

    for(int i = 2;i<Max;i++)
    {
        fac[i] = (fac[i-1]*i)%Mod;

        inv[i] = (Mod-Mod/i)*inv[Mod%i]%Mod;

        facinv[i] = (facinv[i-1]*inv[i])%Mod;
    }
}

LL C(LL n, LL m)
{
    if(n<0 || m<0 || n<m) return 0;

    return (((fac[n]*facinv[m])%Mod)*facinv[n-m])%Mod;
}

LL Lucas(LL n,LL m)
{
    if(n<0 || m<0 || n<m) return 0;

    LL ans = 1;

    while(n || m)
    {
        ans  = (ans*C(n%Mod,m%Mod))%Mod;

        n/=Mod;

        m/=Mod;
    }
    return ans;
}

LL dp[110];

int main()
{
    Init();

    LL n,m;

    int r,z =1;
    while(~scanf("%lld %lld %d",&n,&m,&r))
    {
        for(int i = 1;i<=r;i++)
        {
            scanf("%lld %lld",&p[i].x,&p[i].y);
        }

        p[0] = node(1,1);

        p[r+1]  = node(n,m);

        r++;

        sort(p,p+r+1);

        memset(dp,0,sizeof(dp));

        dp[0] = 1;

        for(int i = 1;i<=r;i++)
        {
            for(int j = 0;j<i;j++)
            {
                node s = p[i]-p[j];

                if(s.x <0 || s.y<0 ||(s.x+s.y)%3) continue;

                LL st = (s.x+s.y)/3;

                //总的方案数
                if(j == 0) dp[i] = ((dp[j]*Lucas(s.x+s.y-st-st,s.x-st))%Mod+Mod)%Mod;
                //不合法的方数

                else dp[i] = ((dp[i]-dp[j]*Lucas(s.x+s.y-st-st,s.x-st))%Mod+Mod)%Mod;
            }
        }
        printf("Case #%d: %lld\n",z++,dp[r]);
    }
    return 0;
}

HDU【5795】——A Simple Nim

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On each turn they can pick any number of candies which come from the same heap(picking no candy is not allowed).To make the game more interesting,players can separate one heap into three smaller heaps(no empty heaps)instead of the picking operation.Please find out which player will win the game if each of them never make mistakes.

Input

Intput contains multiple test cases. The first line is an integer 1≤T≤100, the number of test cases. Each case begins with an integer n, indicating the number of the heaps, the next line contains N integers s[0],s[1],….,s[n−1], representing heaps with s[0],s[1],…,s[n−1] objects respectively.(1≤n≤106,1≤s[i]≤109)

Output

For each test case,output a line whick contains either”First player wins.”or”Second player wins”.

Sample Input

2
2
4 4
3
1 2 4

Sample Output

Second player wins.
First player wins.

Author

UESTC

给你一些堆石子,可以在任意一堆中取出任意多的石子(不可以不取),或者将石子分成三堆,不可以是空堆,问谁最后获胜。我们考虑一堆,Sg打表,会发现x%8 == 0 Sg[x] = x-1,x%8 == 7,Sg[x] = x+1;(x!=0) ,其他Sg[x] = x,然后类似Nim博弈亦或一发就可以了。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
// 打表内容
//int Sg[110];
//
//bool mex[1100];
//
//int GetSg(int x)
//{
// memset(mex,false,sizeof(mex));
//
// for(int i = x-1;i>=0;i--)
// {
// mex[Sg[i]] = true;
// }
//
// int ans;
//
// for(int i = 1;i<x;i++)
// {
// for(int j = 1;j+i<x;j++)
// {
// mex[Sg[i]^Sg[j]^Sg[x-i-j]] = true;
// }
// }
//
// for(int i = 0;i<=1000;i++) if(!mex[i]) return i;
//}
//int main()
//{
// memset(Sg,-1,sizeof(Sg));
//
// Sg[0] = 0;
//
// for(int i = 1;i<=100;i++)
// {
// Sg[i] = GetSg(i);
// }
//
// for(int i = 0;i<=100;i++)
// {
// printf("Sg[%d] = %d\n",i,Sg[i]);
// }
// return 0;
//}

LL Solve(LL x)
{
    if(x == 0) return x;

    if(x%8 ==0) return x-1;

    if(x%8 ==7) return x+1;

    return x;
}

int main()
{
    int T,n;

    LL ans ,x;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d",&n);

        ans = 0;

        for(int i =0 ;i<n;i++)
        {
           scanf("%lld",&x);

           ans^=Solve(x);
        }

        if(ans) printf("First player wins.\n");

        else printf("Second player wins.\n");
    }
    return 0;

}

To My Girlfriend

Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

Dear Guo

i=1nj=1nk=1nl=1nm=1sf(i,j,k,l,m)(i,j,k,laredifferent)

I never forget the moment I met with you.You carefully asked me: “I have a very difficult problem. Can you teach me?”.I replied with a smile, “of course”.”I have n items, their weight was a[i]”,you said,”Let’s define f(i,j,k,l,m) to be the number of the subset of the weight of n items was m in total and has No.i and No.j items without No.k and No.l items.”“And then,” I asked.You said:”I want to know

Sincerely yours,
Liao

Input

The first line of input contains an integer T(T≤15) indicating the number of test cases.
Each case contains 2 integers n, s (4≤n≤1000,1≤s≤1000). The next line contains n numbers: a1,a2,,an(1ai1000) .

Output

Each case print the only number — the number of her would modulo 109 +7 (both Liao and Guo like the number).

Sample Input

2
4 4
1 2 3 4
4 4
1 2 3 4

Sample Output

8
8

令dp[i][j][s1][s2]表示前i个物品填了j的体积,有s1个物品选为为必选,s2个物品选为必不选的方案数(0<=s1,s2<=2),则有转移方程dp[i][j][s1][s2] = dp[i - 1][j][s1][s2] + dp[i - 1][j - a[i]][s1 - 1][s2] + dp[i - 1][j][s1][s2 - 1],边界条件为dp[0][0][0][0] = 1,时间复杂度O(NS × 3^2)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int Mod =1e9+7;

const int Max = 1100;

int dp[2][Max][3][3];

int main()
{
    int T,n,s,x;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d %d",&n,&s);

        memset(dp,0,sizeof(dp));

        dp[0][0][0][0] = 1;

        bool op = true;

        for(int i = 1;i<=n;i++)
        {
            scanf("%d",&x);

            for(int j =s;j>=0;j--)
            {
                for(int s1 = 0; s1 < 3 ;s1++)
                {
                    for(int s2 = 0;s2 < 3;s2++)
                    {
                        dp[op][j][s1][s2] = dp[!op][j][s1][s2];

                        if(j>=x) dp[op][j][s1][s2] =(dp[op][j][s1][s2] + dp[!op][j-x][s1][s2])%Mod;

                        if(s1>0 && j>=x) dp[op][j][s1][s2] = (dp[op][j][s1][s2] + dp[!op][j-x][s1-1][s2])%Mod;

                        if(s2 > 0) dp[op][j][s1][s2] = (dp[op][j][s1][s2] + dp[!op][j][s1][s2-1])%Mod;
                    }
                }
            }

            op =!op;
        }

        int ans =0;

        for(int i = 0;i<=s;i++)
        {
            ans = (ans+dp[!op][i][2][2])%Mod;
        }

        ans  = (((ans*2)%Mod)*2)%Mod;

        printf("%d\n",ans);

    }
    return 0;
}

HDU【5802】——Windows 10

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

Long long ago, there was an old monk living on the top of a mountain. Recently, our old monk found the operating system of his computer was updating to windows 10 automatically and he even can’t just stop it !!
With a peaceful heart, the old monk gradually accepted this reality because his favorite comic LoveLive doesn’t depend on the OS. Today, like the past day, he opens bilibili and wants to watch it again. But he observes that the voice of his computer can be represented as dB and always be integer.
Because he is old, he always needs 1 second to press a button. He found that if he wants to take up the voice, he only can add 1 dB in each second by pressing the up button. But when he wants to take down the voice, he can press the down button, and if the last second he presses the down button and the voice decrease x dB, then in this second, it will decrease 2 * x dB. But if the last second he chooses to have a rest or press the up button, in this second he can only decrease the voice by 1 dB.
Now, he wonders the minimal seconds he should take to adjust the voice from p dB to q dB. Please be careful, because of some strange reasons, the voice of his computer can larger than any dB but can’t be less than 0 dB.

Input

First line contains a number T (1≤T≤300000),cases number.
Next T line,each line contains two numbers p and q (0≤p,q≤10 9 )

Output

The minimal seconds he should take

Sample Input

2
1 5
7 3

Sample Output

4
4

Author

UESTC

给你两个s,t数字,每一次你可以在s增加1,或者减少,如果上次的操作也是减少,那么减少的为上次的两倍,否则为为1,也可以休息。问最少需要多少次的操作,s->t.比较直观的看法是使劲往下降,然后升回来或者使劲往下降然后停顿然后再使劲往下降。。。于是就能将问题变成一个子问题,然后dfs就好需要注意的是由于按up键也可以打断连续向下的功效所以应该记录停顿了几次,以后向上的时候用停顿补回来。

#include <bits/stdc++.h>

using namespace std;

int s,t;

int dfs(int p,int q,int step,int stop)
{
    if(p == q) return step;

    int x  =0;

    while(p-(1 << x) + 1 > q ) x++;

    if(p-(1<<x)+1== q) return step+x;

    int up = q-max(0,p-(1<<x)+1);

    int temp = x+max(0,up-stop);

    return min(step+temp,dfs(p-(1<<(x-1))+1,q,step+x,stop+1));

}

int main()
{
    int T;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d %d",&s,&t);

        if(s<=t) printf("%d\n",t-s);

        else printf("%d\n",dfs(s,t,0,0));
    }
    return 0;
}

你可能感兴趣的:(2016 Multi-University Training Contest 6)