2020计蒜之道决赛题解【Rank200+】

A.蒜头君的序列

在这里插入图片描述
题解:已知n>=m,那么1~m中所有的数都会至少出现一次,最小的质数就是1出现两次,取其和;次小的就是1与2的和。sort一下,if判断输出。

/*
---------------------------------
---------A.蒜头君的序列-----------
---------------------------------
------------Author---------------
---------------------------------
------------XZITXX---------------
---------------------------------
*/
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int N = 1000010;
int n,m,a[N];

int main()
{
    cin>>n>>m;
    for(int i=0; i<n; i++) 
	    scanf("%d",&a[i]);
	    
    sort(a,a+n);
    
    if(a[0]+a[1]==2) puts("2");
    else if (a[0]+a[1]==3) puts("3");
    
    return 0;
}

B.斯摩棱斯克

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题解:建立一个结构体。结构体里面有船只的名字和船的速度。sort一下,枚举第几分钟 i,速度最慢的优先输出,速度最快的只需要输出船名即可。

/*
--------------------------------
------ ---B.斯摩棱斯克----------
--------------------------------
--------------Author------------
--------------------------------
--------------XZITXX------------
--------------------------------
*/
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int N = 1000888;
ll n,m;

struct boat
{
    char s[100];    ll v;
    bool operator< (const boat &w) const {return v<w.v;}
}a[N];


int main()
{
    cin>>n>>m; 
	for(int i=1; i<=n; i++)  
	    scanf("%s %lld", a[i].s, &a[i].v);
	    
    sort(a+1, a+n+1);
    
    for(int i=1; i<n; i++) 
    {
	    ll t = a[i].v*i;  
		printf("%s %lld %lld\n",a[i].s, t/m, m-t%m);
	}
	
    cout<<a[n].s<<endl;
    return 0;
}

C.攀登山峰

在这里插入图片描述
在这里插入图片描述
题解:主席树的一个模板题。

/*
-------------------------------
-----------C.攀登山峰----------
-------------------------------
-------------Author------------
-------------------------------
-------------XZITXX------------
-------------------------------
*/
#include <bits/stdc++.h>
#define ll long long 
using namespace std; 
int n,m,a[1000010],b[1000010],tot,root[1000010 << 2]; 
 
struct node {int l,r,sum;} t[1000010 << 2];

void qaq(int &g,int l,int r) 
{
    t[g=++tot].sum=0;    
	if(l==r)  return;   
	int mid=l+r>>1;
    qaq(t[g].l,l,mid);   
	qaq(t[g].r,mid+1,r);    
	return;
}

void up(int f) { t[f].sum = t[t[f].l].sum+t[t[f].r].sum; } 


void neww(int &k,int la,int l,int r,int p) 
{
    t[k=++tot] = t[la];     
	if(l==r) 
	{ 
	    t[k].sum++;    
		return; 
	}    
	int mid = l+r>>1;
    if(p<=mid)  neww(t[k].l,t[la].l,l,mid,p);    
	else  neww(t[k].r,t[la].r,mid+1,r,p);
    up(k);    
	return;
}

int hky(int x,int y,int l,int r,int k) 
{
    if(l==r)  
	{
	    if(t[x].sum-t[y].sum>=k)  return l;  
		return -1;
	}  
	int mid=l+r>>1,ans=-1;
	
    if(ans==-1 && t[t[x].r].sum>=k)  
	    ans = hky(t[x].r,t[y].r,mid+1,r,k);
	    
    if(ans==-1 && t[t[x].l].sum>=k)  
	    ans = hky(t[x].l,t[y].l,l,mid,k);  
		  
	return ans; 
}

int main()
{
    cin>>n>>m;
    
    for(int i=1; i<=n; i++)
    	cin>>a[i],b[i]=a[i];
	    
    sort(b+1,b+n+1);
    
    int cnt = unique(b+1,b+n+1) - (b+1);
    for(int i=1; i<=n; i++) 
    	a[i] = lower_bound(b+1,b+cnt+1,a[i]) - b;
	
	    
    qaq(root[0],1,n);
    
    for(int i=1; i<=n; i++)
    	neww(root[i],root[i-1],1,n,a[i]);
    
    for(int i=1; i<=m; i++) 
	{
        int l,r,k;  
		cin>>l>>r>>k;  
		k=(r-l+1)/k+1;    
		int t = hky(root[r],root[l-1],1,n,k);
        if(t==-1)  cout<<-1<<endl;  
		else  cout<<b[hky(root[r],root[l-1],1,n,k)]<<endl;
    }
    return 0 ;
}

F.格子

在这里插入图片描述
题解:这是组合数的一个模板题(当查询的数据达到1e5,且可以取模时,需要运用 逆元快速幂预处理所有的阶乘),时间复杂度O(N*logN)

/*
-----------------------------
------------F.格子-----------
-----------------------------
------------Author-----------
-----------------------------
------------XZITXX-----------
-----------------------------
*/
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=3e6+5,mod=998244353;
ll f[N] ;

ll qmi(ll a,ll b)
{
	ll res=1;
	while(b)	
	{
	    if(b&1)  res = res*a%mod;	
	    a = a*a%mod;	
	    b>>=1;
	}
	return res;
}

ll c(int n,int m) 
{
    return 1ll*f[n] * qmi(f[m],mod-2)%mod * qmi(f[n-m],mod-2)%mod;
}

int main() 
{
	int n,m;	
	f[0]=1;
	for(int i=1; i<N; i++)  
	    f[i]=f[i-1]*i%mod;
	cin>>n>>m;	
	cout<<c(n+m-1,n-1)<<endl;
	return 0 ;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值