您的位置:首页 > 大数据 > 人工智能

2015 Multi-University Training Contest 7(hdu5371、5372、5373、5375、5378、5379)(dp+概率Manachar+dfs计数+树状数组)

2015-08-11 23:28 696 查看

Hotaru’s problem

Problem Description

Hotaru Ichijou recently is addicated to math problems. Now she is playing with N-sequence.

Let’s define N-sequence, which is composed with three parts and satisfied with the following condition:

1. the first part is the same as the thrid part,

2. the first part and the second part are symmetrical.

for example, the sequence 2,3,4,4,3,2,2,3,4 is a N-sequence, which the first part 2,3,4 is the same as the thrid part 2,3,4, the first part 2,3,4 and the second part 4,3,2 are symmetrical.

Give you n positive intergers, your task is to find the largest continuous sub-sequence, which is N-sequence.

Input

There are multiple test cases. The first line of input contains an integer T(T<=20), indicating the number of test cases.

For each test case:

the first line of input contains a positive integer N(1<=N<=100000), the length of a given sequence

the second line includes N non-negative integers ,each interger is no larger than 109 , descripting a sequence.

Output

Each case contains only one line. Each line should start with “Case #i: ”,with i implying the case number, followed by a integer, the largest length of N-sequence.

We guarantee that the sum of all answers is less than 800000.

Sample Input

1

10

2 3 4 4 3 2 2 3 4 4

Sample Output

Case #1: 9



[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int maxn=200010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;

int N;
int s[maxn],p[maxn];
set<int> sp;
set<int>::iterator it;

struct node{
    int id,p;
    bool operator<(const node &a) const {
        return p>a.p;
    }
}a[maxn];
void Manachar(int n)
{
    int mx=0,id=0;
    for(int i=0;i<n;i++){
        if(mx>i){
            p[i]=min(p[2*id-i],mx-i);
        } else {
            p[i]=1;
        }
        while(s[i-p[i]]==s[i+p[i]]){
            p[i]++;
        }
        if(i+p[i]>mx){
            mx=i+p[i];
            id=i;
        }
    }
}
int main(){
    int T,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        for(int i=1;i<=2*N-1;i+=2)
        {
            scanf("%d",&s[i]);
            s[i-1]=-1;
        }
        s[2*N]=-1;
        Manachar(2*N+1);
        sp.clear();
        for(int i=1;i<=N;i++){
            a[i].id=i;
            a[i].p=(p[2*i+1])/2;
        }
        sort(a+1,a+1+N);
        int ans=0;
        for(int i=1;i<=N;i++){
            int l=a[i].id-a[i].p;
            int r=a[i].id+a[i].p;
            sp.insert(a[i].id);
            it=sp.lower_bound(l);
            ans=max(ans,a[i].id-*it);
            it=sp.upper_bound(r);
            it--;
            ans=max(ans,*it-a[i].id);
        }
        printf("Case #%d: %d\n",cas++,ans*3);
    }
    return 0;
}


The shortest problem

Problem Description

In this problem, we should solve an interesting game. At first, we have an integer n, then we begin to make some funny change. We sum up every digit of the n, then insert it to the tail of the number n, then let the new number be the interesting number n. repeat it for t times. When n=123 and t=3 then we can get 123->1236->123612->12361215.

Input

Multiple input.

We have two integer n (0<=n<=104 ) , t(0<=t<=105) in each row.

When n==-1 and t==-1 mean the end of input.

Output

For each input , if the final number are divisible by 11, output “Yes”, else output ”No”. without quote.

Sample Input

35 2

35 1

-1 -1

Sample Output

Case #1: Yes

Case #2: No

[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=100010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
LL N,M,sum,res;
void cal(LL x){
    LL f=1;
    LL tmp=x;
    while(x){
        sum+=x%10;
        x/=10;
        f*=10;
    }
    res=(res*f+tmp)%11;
}
int main(){

    int cas=1;
    while(scanf("%I64d%I64d",&N,&M)!=EOF){

        if(N==-1&&M==-1)break;
        //cout<<N<<M<<endl;
        res=sum=0;
        cal(N);
        for(int i=0;i<M;i++){
            cal(sum);
        }
        if(res==0){
            printf("Case #%d: Yes\n",cas++);
        } else {
            printf("Case #%d: No\n",cas++);
        }
    }
    return 0;
}


Gray code

Problem Description

The reflected binary code, also known as Gray code after Frank Gray, is a binary numeral system where two successive values differ in only onebit (binary digit). The reflected binary code was originally designed to prevent spurious output from electromechanical switches. Today, Gray codes are widely used to facilitate error correction in digital communications such as digital terrestrial television and some cable TV systems.

Now , you are given a binary number of length n including ‘0’ , ’1’ and ‘?’(? means that you can use either 0 or 1 to fill this position) and n integers(a1,a2,….,an) . A certain binary number corresponds to a gray code only. If the ith bit of this gray code is 1,you can get the point ai.

Can you tell me how many points you can get at most?

For instance, the binary number “00?0” may be “0000” or “0010”,and the corresponding gray code are “0000” or “0011”.You can choose “0000” getting nothing or “0011” getting the point a3 and a4.

Input

The first line of the input contains the number of test cases T.

Each test case begins with string with ‘0’,’1’ and ‘?’.

The next line contains n (1<=n<=200000) integers (n is the length of the string).

a1 a2 a3 … an (1<=ai<=1000)

Output

For each test case, output “Case #x: ans”, in which x is the case number counted from one,’ans’ is the points you can get at most

Sample Input

2

00?0

1 2 4 8

????

1 2 4 8

Sample Output

Case #1: 12

Case #2: 15

当时真是脑残,分明写个dp就能过。。

[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=200010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int dp[maxn][2];
char s[maxn];
int a[maxn];
int N;
int main(){
    int T,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%s",s+1);
        N=strlen(s+1);
        for(int i=1;i<=N;i++){
            scanf("%d",&a[i]);
        }
        memset(dp,0,sizeof(dp));

        if(s[1]=='1'||s[1]=='?'){
            dp[1][1]=a[1];
        }
        for(int i=2;i<=N;i++){
            if(s[i]=='0'){
                if(s[i-1]=='0'){
                    dp[i][0]=dp[i-1][0];
                }
                if(s[i-1]=='1'){
                    dp[i][0]=dp[i-1][1]+a[i];
                }
                if(s[i-1]=='?'){
                    dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);
                }
            } else if(s[i]=='1'){
                if(s[i-1]=='1'){
                    dp[i][1]=dp[i-1][1];
                }
                if(s[i-1]=='0'){
                    dp[i][1]=dp[i-1][0]+a[i];
                }
                if(s[i-1]=='?'){
                    dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]);
                }
            } else {
                if(s[i-1]=='1'){
                    dp[i][1]=dp[i-1][1];
                    dp[i][0]=dp[i-1][1]+a[i];
                }
                if(s[i-1]=='0'){
                    dp[i][1]=dp[i-1][0]+a[i];
                    dp[i][0]=dp[i-1][0];
                }
                if(s[i-1]=='?'){
                    dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]);
                    dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);
                }
            }
        }
        int ans=0;
        if(s
=='0'){
            ans=dp
[0];
        } else if(s
=='1'){
            ans=dp
[1];
        } else {
            ans=max(dp
[0],dp
[1]);
        }
        printf("Case #%d: %d\n",cas++,ans);
    }
    return 0;
}


Mahjong tree

Problem Description

Little sun is an artist. Today he is playing mahjong alone. He suddenly feels that the tree in the yard doesn’t look good. So he wants to decorate the tree.(The tree has n vertexs, indexed from 1 to n.)

Thought for a long time, finally he decides to use the mahjong to decorate the tree.

His mahjong is strange because all of the mahjong tiles had a distinct index.(Little sun has only n mahjong tiles, and the mahjong tiles indexed from 1 to n.)

He put the mahjong tiles on the vertexs of the tree.

As is known to all, little sun is an artist. So he want to decorate the tree as beautiful as possible.

His decoration rules are as follows:

(1)Place exact one mahjong tile on each vertex.

(2)The mahjong tiles’ index must be continues which are placed on the son vertexs of a vertex.

(3)The mahjong tiles’ index must be continues which are placed on the vertexs of any subtrees.

Now he want to know that he can obtain how many different beautiful mahjong tree using these rules, because of the answer can be very large, you need output the answer modulo 1e9 + 7.

Input

The first line of the input is a single integer T, indicates the number of test cases.

For each test case, the first line contains an integers n. (1 <= n <= 100000)

And the next n - 1 lines, each line contains two integers ui and vi, which describes an edge of the tree, and vertex 1 is the root of the tree.

Output

For each test case, output one line. The output format is “Case #x: ans”(without quotes), x is the case number, starting from 1.

Sample Input

2

9

2 1

3 1

4 3

5 3

6 2

7 4

8 7

9 3

8

2 1

3 1

4 3

5 1

6 4

7 5

8 4

Sample Output

Case #1: 32

Case #2: 16




题解写的好像不太对,当非叶子结点孩子只要小于等于2都要乘2,因为等于2,可以大的放前面小的放后面,或者倒过来,等于一的时候,可以选择放开头或者结尾

[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int maxn=100010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
LL f[maxn];
int N;
LL res;
vector<int> G[maxn];
int dfs(int u,int fa){
    int cnt=1,ns=0,nt=0;
    int len=G[u].size();
    for(int i=0;i<len;i++){
        int v=G[u][i];
        if(v==fa)continue;
        int child=dfs(v,u);
        ns++;
        if(child>1){
            nt++;
        }
        cnt+=child;
    }
    if(nt>2){
        res=0;
    }
    if(nt){
        res=res*2%MOD;
    }
    res=res*f[ns-nt]%MOD;
    return cnt;
}
int main(){
    int T,u,v,cas=1;
    scanf("%d",&T);
    f[0]=1;
    for(int i=1;i<maxn;i++){
        f[i]=f[i-1]*i%MOD;
    }
    while(T--){
        scanf("%d",&N);
        for(int i=0;i<=N;i++){
            G[i].clear();
        }
        for(int i=1;i<N;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        if(N==1){
            printf("Case #%d: 1\n",cas++);
            continue;
        }
        res=1;
        dfs(1,-1);
        printf("Case #%d: %I64d\n",cas++,res*2%MOD);
    }
    return 0;
}


Segment Game

Problem Description

Lillian is a clever girl so that she has lots of fans and often receives gifts from her fans.

One day Lillian gets some segments from her fans Lawson with lengths of 1,2,3… and she intends to display them by adding them to a number line.At the i-th add operation,she will put the segment with length of i on the number line.Every time she put the segment on the line,she will count how many entire segments on that segment.During the operation ,she may delete some segments on the line.(Segments are mutually independent)

Input

There are multiple test cases.

The first line of each case contains a integer n — the number of operations(1<=n<=2∗105,∑n<=7∗105)

Next n lines contain the descriptions of the operatons,one operation per line.Each operation contains two integers a , b.

if a is 0,it means add operation that Lilian put a segment on the position b(|b|<109) of the line.

(For the i-th add operation,she will put the segment on [b,b+i] of the line, with length of i.)

if a is 1,it means delete operation that Lilian will delete the segment which was added at the b-th add operation.

Output

For i-th case,the first line output the test case number.

Then for each add operation,ouput how many entire segments on the segment which Lillian newly adds.

Sample Input

3

0 0

0 3

0 1

5

0 1

0 0

1 1

0 1

0 0

Sample Output

Case #1:

0

0

0

Case #2:

0

1

0

2

Hint

For the second case in the sample:

At the first add operation,Lillian adds a segment [1,2] on the line.

At the second add operation,Lillian adds a segment [0,2] on the line.

At the delete operation,Lillian deletes a segment which added at the first add operation.

At the third add operation,Lillian adds a segment [1,4] on the line.

At the fourth add operation,Lillian adds a segment [0,4] on the line

思路:维护两个树状数组, 第一个维护区间右端点,也就是在右端点加1,第二个维护区间,在区间的左端点加-1,右端点加1,假如说现在线段(l,r)那么答案就是第一个树状数组的到右端点的和,加上第二个的到左端点的和,自己画画图就明白了




可以看到下面的图,如果大矩形的右端点减去左端点的会多出一个编号为1的矩形,那么这个可以用上面图的解决,主需要统计小于大矩形l的和,这样只要不跟大矩形相交的,都会因为-1+1抵消,剩下的-1肯定是因为算到答案里的,所以减掉就行了

[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int maxn=400010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int N,nx;
int X[maxn];
int tree1[maxn],tree2[maxn];
struct OP{
    int a,b,c;
}op[maxn],add[maxn];
int lowbit(int x){
    return x&(-x);
}
void update(int tree[],int x,int val){
    while(x<=nx){
        tree[x]+=val;
        x+=lowbit(x);
    }
}
int getsum(int tree[],int x){
    int sum=0;
    while(x){
        sum+=tree[x];
        x-=lowbit(x);
    }
    return sum;
}
int main(){
    int cas=1;
    while(scanf("%d",&N)!=EOF){
        int cnt=0;
        nx=0;
        for(int i=1;i<=N;i++){
            if(op[i].a==0){
                add[++cnt].a=op[i].a;
                add[cnt].b=op[i].b;
                X[++nx]=op[i].b;
                X[++nx]=op[i].b+cnt;
                op[i].c=cnt;
            }
        }
        int l,r;
        sort(X+1,X+nx+1);
        nx=unique(X+1,X+nx+1)-X-1;
        memset(tree1,0,sizeof(tree1));
        memset(tree2,0,sizeof(tree2));
        printf("Case #%d:\n",cas++);
        for(int i=1;i<=N;i++){
            if(op[i].a==0){
                l=lower_bound(X+1,X+1+nx,op[i].b)-X;
                r=lower_bound(X+1,X+1+nx,op[i].b+op[i].c)-X;
                int num1=getsum(tree1,r)-getsum(tree1,l-1);
                int num2=getsum(tree2,l-1);
                printf("%d\n",num1+num2);
                update(tree1,r,1);
                update(tree2,l,-1);
                update(tree2,r,1);

            } else {
                int x=op[i].b;
                l=lower_bound(X+1,X+1+nx,add[x].b)-X;
                r=lower_bound(X+1,X+1+nx,add[x].b+x)-X;
                update(tree1,r,-1);
                update(tree2,l,1);
                update(tree2,r,-1);
            }
        }
    }
    return 0;
}


Leader in Tree Land

Problem Description

Tree land has n cities, connected by n−1 roads. You can go to any city from any city. In other words, this land is a tree. The city numbered one is the root of this tree.

There are n ministers numbered from 1 to n. You will send them to n cities, one city with one minister.

Since this is a rooted tree, each city is a root of a subtree and there are n subtrees. The leader of a subtree is the minister with maximal number in this subtree. As you can see, one minister can be the leader of several subtrees.

One day all the leaders attend a meet, you find that there are exactly k ministers. You want to know how many ways to send n ministers to each city so that there are k ministers attend the meet.

Give your answer mod 1000000007.

Input

Multiple test cases. In the first line there is an integer T, indicating the number of test cases. For each test case, first line contains two numbers n,k. Next n−1 line describe the roads of tree land.

T=10,1≤n≤1000,1≤k≤n

Output

For each test case, output one line. The output format is Case #x: ans, x is the case number,starting from 1.

Sample Input

2

3 2

1 2

1 3

10 8

2 1

3 2

4 1

5 3

6 1

7 3

8 7

9 7

10 6

Sample Output

Case #1: 4

Case #2: 316512




我的智商是想不到了。。。。。

[code]#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int maxn=1010;
const int maxm=1010;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
int N,K;
vector<int> G[maxn];
int sz[maxn];
LL dp[maxn][maxn];
LL f[maxn],inv[maxn];
void dfs(int u,int fa){
    sz[u]=1;
    for(auto x : G[u]){
        if(x==fa){
            continue;
        }
        dfs(x,u);
        sz[u]+=sz[x];
    }
}
int pow_mul(LL x,LL n){
    LL res=1;
    while(n){
        if(n&1){
            res=res*x%MOD;
        }
        x=x*x%MOD;
        n>>=1;
    }
    return res;
}
int main(){
    int T,u,v,cas=1;
    scanf("%d",&T);
    f[0]=1;
    for(int i=1;i<maxn;i++){
        f[i]=f[i-1]*i%MOD;
        inv[i]=pow_mul(i,MOD-2);
    }
    while(T--){
        scanf("%d%d",&N,&K);
        for(int i=0;i<=N;i++){
            G[i].clear();
            sz[i]=0;
        }
        for(int i=1;i<N;i++){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0);
        dp[0][0]=1;
        for(int i=1;i<=N;i++){
            for(int j=0;j<=K;j++){
                dp[i][j]=dp[i-1][j]*(sz[i]-1)%MOD*inv[sz[i]]%MOD;
                if(j){
                    (dp[i][j]+=dp[i-1][j-1]*inv[sz[i]])%=MOD;
                }
            }
        }
        LL ans=dp
[K]*f
%MOD;
        printf("Case #%d: %I64d\n",cas++,ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: