BestCoder Round #84

来源:互联网 发布:电气原理图软件 编辑:程序博客网 时间:2024/04/28 21:38

HDU【5747】——Aaronson


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

Problem Description

Recently, Peter saw the equation x0+2x1+4x2+...+2mxm=n. He wants to find a solution (x0,x1,x2,...,xm) in such a manner that mi=0xi is minimum and every xi (0≤i≤m) is non-negative.

Input

There are multiple test cases. The first line of input contains an integer T (1≤T≤105), indicating the number of test cases. For each test case:

The first contains two integers n and m (0≤n,m≤109).

Output

For each test case, output the minimum value of mi=0xi.

Sample Input

10
1 2
3 2
5 2
10 2
10 3
10 4
13 5
20 4
11 11
12 3

Sample Output

1
2
2
3
2
2
3
2
3
2

水题:将n分解成二级制,如果m小于n的位数,将剩余的加在最高位就行

#include <iostream>#include <cstdio>using namespace std;typedef long long LL;int n,m;int Get(LL s){    int ans  = 0;    int num = 0;    while(s&&num<m)    {        if(s%2) ans++;        num++;        s>>=1;    }    return ans+s;}int main(){    int T;    scanf("%d",&T);    while(T--)    {       scanf("%d %d",&n,&m);       int ans = Get(n);       printf("%d\n",ans);    }    return 0;}

HDU【5748】——Bellovin


Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

Problem Description

Peter has a sequence a1,a2,...,anand he define a function on the sequence – F(a1,a2,...,an)=(f1,f2,...,fn), where fi is the length of the longest increasing subsequence ending with ai.

Peter would like to find another sequenceb1,b2,...,bnin such a manner that F(a1,a2,...,an) equals to F(b1,b2,...,bn). Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.

The sequence a1,a2,...,an is lexicographically smaller than sequence b1,b2,...,bn, if there is such number i from 1 to n, that ak=bk for 1≤k < i and ai<bi.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first contains an integer n (1≤n≤100000) – the length of the sequence. The second line contains n integers a1,a2,...,an (1≤ai≤109).

Output

For each test case, output n integersb1,b2,...,bn(1bi109) denoting the lexicographically smallest sequence.

Sample Input

3
1
10
5
5 4 3 2 1
3
1 3 5

Sample Output

1
1 1 1 1 1
1 2 3

F(f1,f2,...,fn)=F(a1,a2,...,an​), 显然这个是字典序最小的, 于是要求的序列就是f1,f2,...,fn.用nlogn的时间复杂度。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=110000;int n,val[N],a[N];int len,arr[N];int an[N];int lowbit(int x){    return x&(-x);}void update(int i,int x){    while(x<=len)    {        if(i>arr[x])            arr[x]=i;        x+=lowbit(x);    }}int query(int x){    int ans=0;    while(x)    {        if(arr[x]>ans)            ans=arr[x];        x-=lowbit(x);    }    return ans;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=0; i<n; i++)        {            scanf("%d",&val[i]);            a[i]=val[i];        }        sort(a,a+n);        len=unique(a,a+n)-a;        memset(arr,0,sizeof(arr));        int tmp;        for(int i=0; i<n; i++)        {            val[i]=lower_bound(a,a+len,val[i])-a+1;            tmp=query(val[i]-1)+1;            update(tmp,val[i]);            an[i] = tmp;        }        for(int  i = 0;i<n;i++)        {            if(i) printf(" ");            printf("%d",an[i]);        }        printf("\n");    }    return 0;}

HDU【5749】——Colmerauer


Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

Problem Description

Peter has an n×m matrix M. Let S(a,b) be the sum of the weight all a×b submatrices of M. The weight of matrix is the sum of the value of all the saddle points in the matrix. A saddle point of a matrix is an element which is both the only largest element in its column and the only smallest element in its row. Help Peter find out all the value of S(a,b).

Note: the definition of saddle point in this problem may be different with the definition you knew before.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first contains two integers n and m (1≤n,m≤1000) – the dimensions of the matrix.

The next n lines each contain m non-negative integers separated by spaces describing rows of matrix M (each element of M is no greater than 106).

Output

For each test case, output an integer W=(a=1nb=1mabS(a,b)) mod 232.

Sample Input

3
2 2
1 1
1 1
3 3
1 2 3
4 5 6
7 8 9
3 3
1 2 1
2 3 1
4 5 2

Sample Output

4
600
215

题意:给你一个矩阵,计算所有子矩阵矩阵的值的,既矩阵的面积与鞍点的乘积。考虑每一个鞍点的贡献,假设我们已经知道某个鞍点的的上下左右的有效区间,那么我们可以得出
ans =i=0aj=0bs=0ck=0d(i+j+1)×(s+k+1)=i=0aj=0b(i+j+1)×s=0ck=0d(s+k+1)=[i=0a[(b+1)i]+(a+1)j=0b(j+1)]×[s=0c[s(d+1)]+(c+1)k=0d(k+1)=[(b+1)(a+1)a2+×(b+2)(b+1)(a+1)2]×[(d+1)(c+1)c2+(d+2)(d+1)(c+1)2]=(a+1)(b+1)(b+a+2)2×(c+1)(d+1)(c+d+2)2

我们可以用单调队列处理出每个鞍点在行和列的上下限,然后进行处理。

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <iostream>using namespace std;const int Max = 1100;void read(int &ans){    char ch;    while((ch = getchar())<'0' && ch >'9');    ans = ch-'0';    while((ch = getchar())>='0' && ch<='9')    {        ans = ans*10+ch-'0';    }}int n,m;int arr[Max][Max];int st[Max];int L[Max][Max],R[Max][Max],up[Max][Max],dn[Max][Max];unsigned cal(unsigned a,unsigned b,unsigned c,unsigned d){    return ((a+1)*(b+1)*(a+b+2)/2)*((c+1)*(d+1)*(c+d+2)/2);}int main(){    int T;    read(T);    while(T--)    {        read(n); read(m);        for(int i = 1;i<=n;i++)        {            for(int j = 1;j<=m;j++)            {                read(arr[i][j]);                L[i][j] = 1;                R[i][j] = m;                up[i][j] = 1;                dn[i][j] = n;            }        }        int top;        for(int i = 1;i<=n;i++)        {            top = 0;            st[++top] = 0;            for(int j = 1;j<=m;j++)            {                while(top>1 && arr[i][st[top]] > arr[i][j])                {                    R[i][st[top]] = min(j-1,R[i][st[top]]);                    top--;                }                if(top>1 && arr[i][st[top]] == arr[i][j]) L[i][j] = max(L[i][j],st[top]+1) ;                while(top>1 && arr[i][st[top]] == arr[i][j])                {                    R[i][st[top]] = min(j-1,R[i][st[top]]);                    top --;                }                L[i][j] = max(L[i][j],st[top]+1);                st[++top] = j;            }        }        for(int i = 1;i<=m;i++)        {            top = 0;            st[++top] = 0;            for(int j = 1;j<=n;j++)            {                while(top>1 && arr[st[top]][i]< arr[j][i])                {                    dn[st[top]][i] = min(j-1,dn[st[top]][i]);                    top--;                }                if(top >1  && arr[st[top]][i] == arr[j][i]) up[j][i] =max(up[j][i],st[top]+1);                while(top>1 && arr[st[top]][i] == arr[j][i])                 {                    dn[st[top]][i] = min(j-1,dn[st[top]][i]);                    top--;                }                up[j][i] = max(up[j][i],st[top]+1);                st[++top] = j;            }        }        unsigned int ans = 0;        for(int i = 1;i<=n;i++)        {            for(int j = 1;j<=m;j++)            {                unsigned c1 = j - L[i][j];                unsigned c2 = R[i][j]-j;                unsigned h1 = i - up[i][j];                unsigned h2 = dn[i][j] - i;                unsigned s = arr[i][j];                ans +=cal(c1,c2,h1,h2)*s;            }        }        cout<<ans<<endl;    }    return 0;}

HDU【5750】——Dertouzos


Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

Problem Description

A positive proper divisor is a positive divisor of a number n, excluding n itself. For example, 1, 2, and 3 are positive proper divisors of 6, but 6 itself is not.

Peter has two positive integers n and d. He would like to know the number of integers below n whose maximum positive proper divisor is d.

Input

There are multiple test cases. The first line of input contains an integer T (1≤T≤106), indicating the number of test cases. For each test case:

The first line contains two integers n and d (2≤n,d≤109).

Output

For each test case, output an integer denoting the answer.

Sample Input

9
10 2
10 3
10 4
10 5
10 6
10 7
10 8
10 9
100 13

Sample Output

1
2
1
0
0
0
0
0
4

比赛的时候手残,最后T了。问小于n的数中有多少个数的最大的因子是d,显然的事是d一定和素数相乘,并且小于等于min(n1d,d),但是当d不是素数的时候,我们找到d的最小质因子s,那么ans就是小于等于min(n1d,d,s)的素数的个数。

#include<iostream>#include<cstdio>#include<cstring>#include <cmath>#include<algorithm>using namespace std;const int Max = 1e7+100;int prime[Max];int vis[Max];int num[Max];void Get(){    prime[0] =0 ;    num[0] = num[1] = 0;    for(int i = 2; i<Max; i++)    {        if(!vis[i])        {            prime[++prime[0]] = i;            for(int j =i+i; j<Max; j+=i)            {                if(!vis[j]) vis[j] = i;            }        }        num[i] = num[i-1];        if(!vis[i]) num[i]++;    }}int n,p;int main(){    Get();    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d %d",&n,&p);        int s=(n-1)/p;        if(s <= 1)        {            printf("0\n");            continue;        }        int ans = 0;        for(int i = 1;i<=prime[0] && prime[i]<=s;i++)        {            ans++;            if(p%prime[i] == 0)            {                break;            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击