2017 Multi-University Training Contest

来源:互联网 发布:岚皋数据运营招聘 编辑:程序博客网 时间:2024/06/08 10:14

题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=761

Kanade's sum

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2097    Accepted Submission(s): 164


Problem Description
Give you an array A[1..n]of length n

Let f(l,r,k) be the k-th largest element of A[l..r].

Specially , f(l,r,k)=0 if rl+1<k.

Give you k , you need to calculate nl=1nr=lf(l,r,k)

There are T test cases.

1T10

kmin(n,80)

A[1..n] is a permutation of [1..n]

n5105
 

Input
There is only one integer T on first line.

For each test case,there are only two integers n,k on first line,and the second line consists of n integers which means the array A[1..n]
 

Output
For each test case,output an integer, which means the answer.
 

Sample Input
15 21 2 3 4 5
 

Sample Output
30
 

Statistic | Submit | Clarifications | Back

解析:我们只要求出对于一个数xx左边最近的kk个比他大的和右边最近kk个比他大的,扫一下就可以知道有几个区间的kk大值是xx.
我们考虑从小到大枚举xx,每次维护一个链表,链表里只有>=x>=x的数,那么往左往右找只要暴力跳kk次,删除也是O(1)O(1)的。
时间复杂度:O(nk)O(nk)

代码:

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int N = 500009;int a[N];int s[83], e[83];inline void q_read(int &num){    char ch;    while(true)    {        ch = getchar();        if(isdigit(ch))        {            num = ch - '0';            break;        }    }    while(ch=getchar(), isdigit(ch)) num = num*10+ch-'0';}int main(){    int t, n, k;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &n, &k);        for(int i = 1; i <= n; i++) q_read(a[i]);        LL ans = 0ll; k--;        for(int i = 1; i <= n; i++)        {            int p, d, len1, len2;            len1 = len2 = 0;            for(int j = i+1; j <= n; j++)            {                if(a[j] > a[i]) s[len1++] = j;                if(len1 > k) break;            }            if(len1 == k + 1)            {                p = s[len1-1];                len1--;                d = p - s[len1-1];            }            else if(len1 == 0) d = n - i + 1;            else d = n - s[len1-1] + 1;            for(int j = i; j >= 1; j--)            {                if(a[j] > a[i])                {                    e[len2++] = j;                    if(len1 + len2 > k)                    {                        if(len1)                        {                            p = s[len1-1];                            len1--;                            if(len1)                            {                                d = p - s[len1-1];                            }                            else d = p - i;                        }                    }                }                if(len1 + len2 == k) ans += (LL)a[i]*d;                else if(len1 + len2 > k) break;            }        }        printf("%lld\n", ans);    }    return 0;}

RXD and math

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1832    Accepted Submission(s): 745


Problem Description
RXD is a good mathematician.
One day he wants to calculate:
i=1nkμ2(i)×nki

output the answer module 109+7.
1n,k1018
μ(n)=1(n=1)

μ(n)=(1)k(n=p1p2pk)

μ(n)=0(otherwise)

p1,p2,p3pk are different prime numbers
 

Input
There are several test cases, please keep reading until EOF.
There are exact 10000 cases.
For each test case, there are 2 numbers n,k.
 

Output
For each test case, output "Case #x: y", which means the test case number and the answer.
 

Sample Input
10 10
 

Sample Output
Case #1: 999999937
 

Statistic | Submit | Clarifications | Back


解析:自己敲个莫比乌斯,暴力找下规律得到,求n^k%mod

代码:

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1000009;const LL mod = 1e9+7ll;//int pri[N], ispri[N], m[N];//void init()//{//    int len = 0;//    memset(ispri, 0, sizeof(ispri));//    for(int i = 2; i <= 100000; i++)//    {//        if(ispri[i]) continue;//        pri[len++] = i;//        for(int j = i*2; j <= 100000; j += i) ispri[i] = 1;//    }//    m[1] = 1;//    for(int i = 2; i <= 100000; i++)//    {//        int num = i, ans = 0;//        for(int j = 0; j < len && pri[j] <= i; j++)//        {//            if(num % pri[j] == 0)//            {//                num /= pri[j];//                if(num % pri[j] == 0)//                {//                    ans = 0;//                    break;//                }//                ans++;//            }//        }//        if(ans) m[i] = ans&1 ? -1 : 1;//        else m[i] = ans;//    }////    //for(int i = 1; i <= 30; i++) printf("%d ", m[i]);////}LL q_mod(LL a, LL b){    LL ans = 1ll;    a = a % mod;    while(b)    {        if(b&1) ans = ans * a % mod;        a = a * a % mod;        b >>= 1;    }    return ans%mod;}int main(){    LL n, k;    int cnt = 0;    while(~scanf("%lld%lld", &n, &k))    printf("Case #%d: %lld\n", ++cnt, q_mod(n, k));    return 0;}

RXD's date

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1426    Accepted Submission(s): 1085


Problem Description
As we all know that RXD is a life winner, therefore he always goes out, dating with his female friends.
Nevertheless, it is a pity that his female friends don't like extremely hot temperature. Due to this fact, they would not come out if it is higher than 35 degrees.
RXD is omni-potent, so he could precisely predict the temperature in the next t days, but he is poor in counting.
He wants to know, how many days are there in the next t days, in which he could go out and date with his female friends.
 

Input
There is only one test case.

The first line consists of one integer t.

The second line consists of t integers ci which means the temperature in the next t days.

1t1000 

0ci50
 

Output
Output an integer which means the answer.
 

Sample Input
533 34 35 36 37
 

Sample Output
3
 

Statistic | Submit | Clarifications | Back

解析:一个签到题,目的在于吐槽浙江的高温
统计有多少数<=35<=35即可。

代码:

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int N = 1000009;int main(){    int n, num;    int ans = 0;    scanf("%d", &n);    for(int i = 1; i <= n; i++)    {        scanf("%d", &num);        if(num <= 35) ans++;    }    printf("%d\n", ans);    return 0;}



原创粉丝点击