牛客小白月赛16 A,B,C,D,E,F,G,H

这次比赛是在家里打的。比赛一半的时候才想起来,从1小时40分钟开始写的。写完5道题之后还剩半个多小时,觉得也写不出什么题了,就直接放弃了(其实是发现6道也进不了rank50)。

Contest:https://ac.nowcoder.com/acm/contest/949#question

A-小石的签到题

题目链接:https://ac.nowcoder.com/acm/contest/949/A

题目大意:中文题,较好理解题意。

思路:假设后取的人胜,那么只要先取的人取了1,那么后取的人相当于先取了,先取的人胜。假设先取的人胜,那么先取的人胜利了。。。发现总是先取的人胜利。注意只有一个石子的特判。

ACCode:

#include<iostream>
int main(){
    int n;std::cin>>n;
    if(n==1) std::cout<<"Yang\n";
    else std::cout<<"Shi\n";
}

B-小雨的三角形

题目链接:https://ac.nowcoder.com/acm/contest/949/B

题目大意:中文题。

思路:直接暴力打一遍表,然后得出前缀和即可。

ACCode:

ll A[MAXN][MAXN];
ll Ans[MAXN];

int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        A[i][1]=A[i][i]=i;
        for(int j=2;j<i;++j){
            A[i][j]=(A[i-1][j-1]+A[i-1][j])%MOD;
        }
        for(int j=1;j<=i;++j){
            Ans[i]+=A[i][j];Ans[i]%=MOD;
        }
    }
    while(m--){
        int a,b;scanf("%d%d",&a,&b);
        ll ans=0;
        for(int i=a;i<=b;++i){
            ans=(ans+Ans[i])%MOD;
        }printf("%lld\n",ans);
    }
}

C-小石的海岛之旅

题目链接:https://ac.nowcoder.com/acm/contest/949/C

题目大意:中文题。

思路:暴力就好了,出题人也是这么说的。有另一种方法:由于水位单调上升,因此在地形i被水淹没时,查看地形i-1和i+1有没有被淹没,被淹没,-1;没被淹没,+1;一个被淹没一个没被淹没,不变。

我就暴力过了QAQ。

ACCode:

const int MAXN=1e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

int H[MAXN];

int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",&H[i]);
    }
    while(m--){
        int h;scanf("%d",&h);
        int ans=0,s=0;
        for(int i=1;i<=n;++i){
            if(H[i]>h){
                if(s==0){
                    s=1;ans++;
                }
            }
            else{
                if(s){
                    s=0;
                }
            }
        }printf("%d\n",ans);
    }
}

D-小阳买水果

题目链接:https://ac.nowcoder.com/acm/contest/949/D

题目大意:中文题

思路:得出他们的前缀和Sum,发现,只有Sum[r]-Sum[l]>0的才是答案区间。因此,从左到右枚举r,同时维护单调递减栈。二分栈中的元素,找到符合要求的位置,取最大值即可。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
#include<time.h>

#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<ll,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register 
const int MAXN=2e6+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

ll A[MAXN],Sum[MAXN];
Pair Stk[MAXN];int top; 
int n;

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld",&A[i]);
	}
	for(int i=1;i<=n;++i){
		Sum[i]=Sum[i-1]+A[i];
	}
//	for(int i=1;i<=n;++i) printf("%lld ",Sum[i]);printf("\n");
	int Ans=0;
	top=0;Stk[++top]=make_pair(0,0);
	for(int i=1;i<=n;++i){//枚举右区间r,同时维护单调递减栈 
		if(Sum[i]<Stk[top].first) Stk[++top]=make_pair(Sum[i],i);
		else if(Sum[i]==Stk[top].first) ;
		else{
			int l=1,r=top,mid;
			while(l<=r){
				mid=(l+r)>>1;
				if(Stk[mid].first<Sum[i]) r=mid-1;
				else l=mid+1;
			}Ans=max(Ans,i-Stk[l].second);
//			printf("l=%lld,r=%d\n",Stk[l].second,i);
		}
//		for(int i=1;i<=top;++i) printf("%lld ",Stk[i].first);printf("\n");
	}printf("%d\n",Ans);
}

E-小雨的矩阵

题目链接:https://ac.nowcoder.com/acm/contest/949/E

题目大意:中文题。

思路:由于数据比较水,搜索去重即可。想怎么搜怎么搜。

ACCode:

const int MAXN=10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

struct Node{
    int i,j,Sum;
    Node(int _i=0,int _j=0,int _Sum=0){
        i=_i;j=_j;Sum=_Sum;
    }
};
int A[MAXN][MAXN];
map<ll,ll> Vis;

int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            scanf("%d",&A[i][j]);
        }
    }queue<Node> que;que.push(Node(1,1,A[1][1]));
    int ans=0;
    while(que.size()){
        Node u=que.front();que.pop();
        if(u.i==n&&u.j==n){
            if(Vis[u.Sum]==0){
                Vis[u.Sum]=1;ans++;
            }
        }
        Node v;
        if(u.i<n){v=Node(u.i+1,u.j,u.Sum+A[u.i+1][u.j]);que.push(v);}
        if(u.j<n){v=Node(u.i,u.j+1,u.Sum+A[u.i][u.j+1]);que.push(v);}
    }printf("%d\n",ans);
    
}

F-小石的妹子

题目链接:https://ac.nowcoder.com/acm/contest/949/F

题目大意:中文题。

思路:将妹子按照一个属性A对妹子从大到小排序,在将另一个属性B进行排序,对于每个妹子,在B的有序数组中二分出该妹子的位置Pos,则Pos后面的都是这个妹子等级之上的。将这个妹子rank刷新为max{rank[Pos,n]}+1。

ACCode:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
// srand(unsigned)time(NULL));rand();
 
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
 
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
 
 
class SegTree{
    int Max[MAXN<<2];
 
    public:
        void Build(){
            clean(Max,0);
        }
        void Update(int ql,int qr,int val,int l,int r,int rt){
            if(ql<=l&&qr>=r){
                Max[rt]=val;return ;
            }int mid=(l+r)>>1;
            if(ql<=mid) Update(ql,qr,val,l,mid,rt<<1);
            if(qr>mid) Update(ql,qr,val,mid+1,r,rt<<1|1);
            Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
        }
        int QueryMax(int ql,int qr,int l,int r,int rt){
            if(ql<=l&&r<=qr) return Max[rt];
            int mid=(l+r)>>1;
            int ans=-1;
            if(ql<=mid) ans=max(QueryMax(ql,qr,l,mid,rt<<1),ans);
            if(qr>mid) ans=max(QueryMax(ql,qr,mid+1,r,rt<<1|1),ans);
            return ans;
        }
};
struct Peo{
    int a,b,id;
    Peo(int _a=0,int _b=0,int _id=0){
        a=_a;b=_b;id=_id;
    }
};
SegTree Seg;
Peo Girl[MAXN];
int B[MAXN];
int Ans[MAXN];
int n;
 
int Cmp(Peo a,Peo b){
    return a.a>b.a;
}
int GetPos(int Key){
    int l=1,r=n,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(B[mid]==Key) return mid;
        else if(B[mid]>Key) r=mid-1;
        else l=mid+1;
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        int a,b;scanf("%d%d",&a,&b);
        Girl[i]=Peo(a,b,i);B[i]=b;
    }Seg.Build();
    sort(Girl+1,Girl+1+n,Cmp);
    sort(B+1,B+1+n);
    for(int i=1;i<=n;++i){
        int pos=GetPos(Girl[i].b);
        Ans[Girl[i].id]=Seg.QueryMax(pos,n,1,n,1)+1;
        Seg.Update(pos,pos,Ans[Girl[i].id],1,n,1);
    }
    for(int i=1;i<=n;++i) printf("%d\n",Ans[i]);
}

G-小石的图形

题目链接:https://ac.nowcoder.com/acm/contest/949/G

题目大意:中文题

思路:提上很明显了啊是个半圆。

ACCode:

const int MAXN=1e2+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

int main(){
    double n;scanf("%lf",&n);
    printf("%.3lf\n",n*n/(2.0*PI));
}

H-小阳的贝壳

题目链接:https://ac.nowcoder.com/acm/contest/949/H

题目大意:中文题

思路:建立差分数组线段树记录区间差分的值。

操作二:差分数组维护A[i]与A[i-1]的差,因此直接维护差分数组区间最大最小值就好了。

操作三:gcd(a,b,c)=gcd(a,gcd(b,c))=gcd(a,gcd(b,c-b))=gcd(a,b-a,c-b);就是差分数组。

其中a由于没有改变,所以是差分数组的[1,l]区间之和,后面的就是gcd(b-a,c-d.....)的值了。因此我们只用维护区间和Sum,区间GCD就好了。

ACCode:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
  
#include<stdio.h>
#include<string.h> 
#include<math.h> 
#include<time.h>

#include<map>  
#include<set>
#include<deque> 
#include<queue> 
#include<stack> 
#include<bitset>
#include<string> 
#include<fstream>
#include<iostream> 
#include<algorithm> 
using namespace std; 
  
#define ll long long 
#define Pair pair<ll,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
//  register 
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;

class SegTree{
	ll Sum[MAXN<<2],GCD[MAXN<<2],MAX[MAXN<<2],MIN[MAXN<<2];
	//Sum差分区间和。 
	
	void PushUp(int rt){
		Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
		GCD[rt]=gcd(GCD[rt<<1],GCD[rt<<1|1]);
		MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
		MIN[rt]=min(MIN[rt<<1],MIN[rt<<1|1]);
	}
	public:
		ll gcd(ll a,ll b){
			if(b==0) return a;
			else return abs(gcd(b,a%b));
		}
		void Build(int l,int r,int rt,ll A[]){
			if(l==r){
				Sum[rt]=MAX[rt]=MIN[rt]=GCD[rt]=A[l]-A[l-1];
				return ;
			}
			int mid=(l+r)>>1;
			Build(l,mid,rt<<1,A);Build(mid+1,r,rt<<1|1,A);
			PushUp(rt);
		}
		void Update(int ql,int qr,ll val,int l,int r,int rt){
			if(ql<=l&&r<=qr){
				Sum[rt]+=val;GCD[rt]+=val;MAX[rt]+=val;MIN[rt]+=val;
				return ;
			}int mid=(l+r)>>1;
			if(ql<=mid) Update(ql,qr,val,l,mid,rt<<1);
			if(qr>mid) Update(ql,qr,val,mid+1,r,rt<<1|1);
			PushUp(rt);
		}
		ll QueryMax(int ql,int qr,int l,int r,int rt){
			if(ql<=l&&r<=qr) return MAX[rt];
			ll res=-INF64,mid=(l+r)>>1;
			if(ql<=mid) res=max(res,QueryMax(ql,qr,l,mid,rt<<1));
			if(qr>mid) res=max(res,QueryMax(ql,qr,mid+1,r,rt<<1|1));
			return res; 
		}
		ll QueryMin(int ql,int qr,int l,int r,int rt){
			if(ql<=l&&r<=qr) return MIN[rt];
			ll res=INF64,mid=(l+r)>>1;
			if(ql<=mid) res=min(res,QueryMin(ql,qr,l,mid,rt<<1));
			if(qr>mid) res=min(res,QueryMin(ql,qr,mid+1,r,rt<<1|1));
			return res;
		}
		ll QuerySum(int ql,int qr,int l,int r,int rt){
			if(ql<=l&&r<=qr) return Sum[rt];
			ll res=0,mid=(l+r)>>1;
			if(ql<=mid) res+=QuerySum(ql,qr,l,mid,rt<<1);
			if(qr>mid) res+=QuerySum(ql,qr,mid+1,r,rt<<1|1);
			return res; 
		}
		ll QueryGCD(int ql,int qr,int l,int r,int rt){
			if(ql<=l&&r<=qr) return GCD[rt];
			ll res=0,mid=(l+r)>>1;
			if(ql<=mid) res=gcd(res,QueryGCD(ql,qr,l,mid,rt<<1));
			if(qr>mid) res=gcd(res,QueryGCD(ql,qr,mid+1,r,rt<<1|1));
			return res;
		}
};
SegTree Seg;
ll A[MAXN];
int n,m;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%lld",&A[i]);
	Seg.Build(1,n,1,A);
	while(m--){
		int opt,l,r;scanf("%d%d%d",&opt,&l,&r);
		if(opt==1){
			ll val;scanf("%lld",&val);
			Seg.Update(l,l,val,1,n,1);
			if(r<n) Seg.Update(r+1,r+1,-val,1,n,1);
		}
		else if(opt==2){
			if(l==r) printf("0\n");
			else printf("%lld\n",max(Seg.QueryMax(l+1,r,1,n,1),-1ll*Seg.QueryMin(l+1,r,1,n,1)));
		}
		else{
			printf("%lld\n",Seg.gcd(Seg.QuerySum(1,l,1,n,1),Seg.QueryGCD(l+1,r,1,n,1))); 
		}
	} 
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值