牛客每日练习----队列重排,吃货,K序列

我喜欢给自己压力,必须得定一个很高的目标,逼自己朝着这个目标前进,不管会不会实现,都是一个动力。                                      ----喻言

链接:https://ac.nowcoder.com/acm/problem/15614
来源:牛客网

题目描述

有n(n≤500000) 个人排成一列,把他们解散后重排,使得"重排后前方" 跟"原排列前方" 一样的人不超过k(k<n) 个,问有几种方法数,答案请mod (109+7) 输出。
举例来说,有五个人编号为1∼5 间的整数,最初的排列由前至后依序为1, 2, 3, 4, 5,重排列后顺序由前至后变为1, 3, 4, 2, 5,其中只要编号为4 的人,"原排列前方" 跟"重排后前方" 都是编号为3 的人,故"重排后前方" 跟"原排列前方" 一样的人只有1 人。
原排列的第 1 个人和重排后的第 1 个人一定不会是「"重排后前方" 跟 "原排列前方" 一样的人」。

输入描述:

输入只有一行,有两个正整数 n,k,满足 1≤k<n≤500000。

输出描述:

请输出一行包含一个小于 109+7 的非负整数,表示总共的方法数 mod (109+7)。

示例1

输入

复制

3 1

输出

复制

5

说明

当 n=3 时,假设三个人在原排列的编号由前到后依序为 1、2、3。
重排列后的情形可分为下列 3 种:
"重排后前方" 和 "原排列前方" 一样的人数为 0 的有:1 3 2,2 1 3,3 2 1,3 种。
"重排后前方" 和 "原排列前方" 一样的人数为 1 的有:2 3 1,3 1 2,2 种。
"重排后前方" 和 "原排列前方" 一样的人数为 2 的仅有 1 2 3,1 种。

示例2

输入

复制

10 7

输出

复制

3628790
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <sstream>
#include <complex>
#include <iomanip>
#include<climits>//INT_MAX
#define PP pair<ll,int>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3fll
#define dinf 1000000000000.0
typedef long long ll;
using namespace std;
int const N=2000010;
int const mod=1e9+7;
const int maxn=500010;
int n,k,a[maxn],ny[maxn],f[maxn];
int add(int x,int y)
{
    x+=y;
    if(x>=mod)
		x-=mod;
    return x;
}
int mul(int x,int y)
{
    ll z=1ll*x*y;
    return z-z/mod*mod;
}
void init(int n=5e5)
{
    ny[1]=1;
    for(int i=2;i<=n;i++)	
		ny[i]=mul(mod-mod/i,ny[mod%i]);
    ny[0]=1;
    for(int i=1;i<=n;i++)
		ny[i]=mul(ny[i-1],ny[i]);
    f[0]=1;
    for(int i=1;i<=n;i++)
		f[i]=mul(i,f[i-1]);
}
int C(int n,int m)
{
    return mul(f[n],mul(ny[m],ny[n-m]));
}
int main()
{
	int jg=0;
    init();
    scanf("%d%d",&n,&k);
    a[1]=1,a[2]=1;
    for(int i=3;i<=n;i++)
		a[i]=add(mul(i-1,a[i-1]),mul(i-2,a[i-2]));
    for(int i=0;i<=k;i++)
		jg=add(jg,mul(C(n-1,i),a[n-i]));
    printf("%d\n",jg);
    return 0;
}

链接:https://ac.nowcoder.com/acm/problem/15664
来源:牛客网

题目描述

作为一个标准的吃货,mostshy又打算去联建商业街觅食了。
混迹于商业街已久,mostshy已经知道了商业街的所有美食与其价格,而且他给每种美食都赋予了一个美味度,美味度越高表示他越喜爱这种美食。
mostshy想知道,假如带t元去商业街,只能吃一种食物,能够品味到的美食的美味度最高是多少?

输入描述:

第一行是一个整数T(1 ≤ T ≤ 10),表示样例的个数。
以后每个样例第一行是两个整数n,m(1 ≤ n,m ≤ 30000),表示美食的种类数与查询的次数。
接下来n行,每行两个整数分别表示第i种美食的价格与美味度di,ci (1 ≤ di,ci ≤ 109)。
接下来m行,每行一个整数表示mostshy带t(1 ≤ t ≤ 109)元去商业街觅食。

输出描述:

每个查询输出一行,一个整数,表示带t元去商业街能够品味到美食的最高美味度是多少,如果不存在这样的美食,输出0。

示例1

输入

复制

1
3 3
1 100
10 1000
1000000000 1001
9
10
1000000000

输出

复制

100
1000
1001

说明

大量的输入输出,请使用C风格的输入输出。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <sstream>
#include <complex>
#include <iomanip>
#include<climits>//INT_MAX
#define PP pair<ll,int>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3fll
#define dinf 1000000000000.0
typedef long long ll;
using namespace std;
int const N=2000010;
int const mod=1e9+7;
const int maxn=30010;
int b[maxn],T;
struct node {
    int d;
	int c;
}p[maxn];
bool cmp(node A, node B){
    if (A.d==B.d)   
		return A.c>B.c;
    return A.d<B.d;
}
int main(){
    scanf("%d", &T);
    while(T--){
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i=0; i<n; i++)
            scanf("%d%d", &p[i].d , &p[i].c);
        sort(p, p+n, cmp);
        b[0]=p[0].d;
        for (int i=1; i<n; i++){
            p[i].c=max(p[i].c, p[i-1].c);
            b[i]=p[i].d;
        }
        while (m--){
            int t;
            scanf("%d", &t);
            int ls=upper_bound(b, b+n, t)-b-1;
            if (t<b[0])    
				printf("0\n");
            else     
				printf("%d\n", p[ls].c);
        }
    }
    return 0;
}

链接:https://ac.nowcoder.com/acm/problem/15613
来源:牛客网

题目描述

给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”。现在要你 对数组 a 求出最长的子序列的长度,满足这个序列是 K 序列。 

输入描述:

第一行为两个整数 n, K, 以空格分隔,第二行为 n 个整数,表示 a[1] ∼ a[n],1 ≤ n ≤ 105 , 1 ≤ a[i] ≤ 109 , 1 ≤ nK ≤ 107

输出描述:

输出一个整数表示最长子序列的长度 m

示例1

输入

复制

7 5
10 3 4 2 2 9 8

输出

复制

6
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <sstream>
#include <complex>
#include <iomanip>
#include<climits>//INT_MAX
#define PP pair<ll,int>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3fll
#define dinf 1000000000000.0
typedef long long ll;
using namespace std;
int const N=100000+10;
int const mod=1e9+7;
const int maxn=10000000+10;
int n,k,s[N],ls[maxn],dp[maxn];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%d",&s[i]);
    for(int i=0;i<n;i++){
        for(int j=0;j<k;j++){
            if(j==0||ls[j]!=0)
                dp[(j+s[i])%k]=ls[j]+1;
        }
        for(int j=0;j<k;j++)
            ls[j]=max(ls[j],dp[j]);
    }
    printf("%d\n",dp[0]);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值