这次比赛是在家里打的。比赛一半的时候才想起来,从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)));
}
}
}