2024牛客暑期多校第一场补题报告

C-Sum of Suffix Sums

Sum of Suffix Sums

题目类型:签到,数学。

解题思路:题目要求输出每次操作后当前序列后缀和的和,可以发现每个ai在总和中出现i次,维护一个数组存放i*ai的前缀和即可。

AC代码:

#include<iostream>

using namespace std;
typedef long long LL;

const LL N=500010,mod=1000000007;
LL ans[N];
int idx=0;

void op(){
	int t,v;
	cin>>t>>v;
	idx=idx-t+1;
	ans[idx]=(ans[idx-1]+v*idx)%mod;
	cout<<ans[idx]<<'\n';
}

int main()
{
	int q;cin>>q;
	while(q--){
		op();
	}
	return 0;
}

H-World Finals

World Finals

题目类型:签到。

解题思路:第一场最优排名为除lzr010506其他double-qualified的队伍都参加第二场,第二场最优排名为除lzr010506其他double-qualified的队伍都参加第二场,两个排名取最优。

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<utility>

using namespace std;

map<string,pair<int,int> >a,b;

int main()
{
	int n;cin>>n;
	pair<int,int>x1,x2;
	for(int i=1;i<=n;i++){
		string s;
		int p,t;
		cin>>s>>p>>t;
		a[s]={p,t};
		if(s=="lzr010506") x1={p,t};
	}
	int m;cin>>m;
	for(int i=1;i<=m;i++){
		string s;
		int p,t;
		cin>>s>>p>>t;
		b[s]={p,t};
		if(s=="lzr010506") x2={p,t};
	}
	
	int rk1=1,rk2=1;
	for(auto x:a){
		if(b.count(x.first)){
			continue;
		}
		else if((x.second.first==x1.first && x.second.second<x1.second) || x.second.first>x1.first){
			rk1++;
		}
	}
	for(auto x:b){
		if(a.count(x.first)){
			continue;
		}
		else if((x.second.first==x2.first && x.second.second<x2.second) || x.second.first>x2.first){
			rk2++;
		}
	}
	
	cout<<min(rk1,rk2);
	
	return 0;
}

I-Mirror Maze

Mirror Maze

题目类型:搜索。

解题思路:所有的光线都是环或链(射出边界),遍历所有的环和链,记录每个光源(不同位置不同方向共4nm个)的答案,每次询问输出即可。

AC代码:

#include<iostream>
#include<string>
#include<utility>
#include<set>

using namespace std;
typedef pair<int,int> PII;

/*
0:above
1:below
2:left
3:right
*/
const int N=1010;
char s[N][N];
int n,m;
int vis[N][N][4];
int dp[N][N][4];        //存放每个光源的答案
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
set<PII>st;

int alter(int x,int y,int d){
    int nd=d;
    if(s[x][y]=='|'){
        if(d==2) nd=3;
        else if(d==3) nd=2;    
    }
    else if(s[x][y]=='-'){
        if(d==0) nd=1;
        else if(d==1) nd=0;
    }
    else if(s[x][y]=='/'){
        if(d==0) nd=3;
        else if(d==1) nd=2;
        else if(d==2) nd=1;
        else if(d==3) nd=0;
    }
    else{
        if(d==0) nd=2;
        else if(d==1) nd=3;
        else if(d==2) nd=0;
        else if(d==3) nd=1;
    }
    return nd;
}

void dfs(int x,int y,int d){
    if(x>n || y>m || x<1 || y<1) return;
    if(vis[x][y][d]==2) return;

    int nd=alter(x,y,d);    //经过当前镜面后的方向
    vis[x][y][d]++;
    dfs(x+dx[nd],y+dy[nd],nd);
    vis[x][y][d]=0;
    
    //若发生反射则加入集合st,st存放反射当前光源的镜面
    if(nd!=d) st.insert({x,y});
    dp[x][y][d]=st.size();
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                if(!dp[i][j][k]){
                    //处理新的光源的答案时清空st
                    st.clear();
                    dfs(i,j,k);
                }
            }
        }
    }
    
    int q;cin>>q;
    while(q--){
        int u,v;
        string dir;
        cin>>u>>v>>dir;
        int id,ans;
        if(dir=="above"){
            id=0;
        } 
        else if(dir=="below"){
            id=1;
        }
        else if(dir=="left"){
            id=2;
        }
        else{
            id=3;
        }
        //输入的光源位置是不反射光的,有效光源位置应该是下一个位置
        ans=dp[u+dx[id]][v+dy[id]][id];
        cout<<ans<<'\n';
    }
    return 0;
}

A-A Bit Common

A Bit Common

题目类型:数学。

解题思路:只有最后一位为1的数按位与后才可能是1。设n个数中有i个数最后一位为1(符合要求的子序列),对于这i个数的其它位(共m-1位)中的任意一位,至少有一个数的这一位为0,则这i个数的方案数为(2^i-1)^(m-1);对于其他n-i个数,除最后一位为0外其他位可以任取,则这n-i个数的方案数位2^((m-1)*(n-i));因为符合要求的子序列和其他数位置可以任选,所以最后答案为

ans=eq?%5Csum%20_%7Bi%3D1%7D%5E%7Bn%7DC(n,i)*(2^i-1)^(m-1)*2^((m-1)*(n-i))%q。

AC代码:

#include<iostream>

using namespace std;
typedef long long LL;
const int N=5010;
LL n,m,q;
LL c[N][N];

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

void init(){
	for(int i=0;i<N;i++){
		for(int j=0;j<=i;j++){
			if(!j) c[i][j]=1;
			else c[i][j]=(c[i-1][j-1]+c[i-1][j])%q;
		}
	}
}

int main()
{
    cin>>n>>m>>q;
    init();
    LL ans=0;
    for(int i=1;i<=n;i++){
        LL res=c[n][i];
        res=(res*qmi(2,(n-i)*(m-1),q))%q;
        res=(res*qmi(qmi(2,i,q)-1,m-1,q))%q;
        ans=(ans+res)%q;
    }
    cout<<ans<<'\n';
    return 0;
}

 

 

 

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值