2019牛客暑期多校训练营(第一场)

A:Equivalent Prefixes

题意:

若$\text{RMQ(u,l,r)=RMQ(v,l,r)}$ for all $1{\leq}l{\leq}r{\leq}m$,则为$\text{equivalent}$

其中$\text{RMQ(w,l,r)}$的定义是${[l,r]}$区间内最小数的下标

给两个数组,每组元素各不相同,求最大的$p{\leq}n\ where\ \{a_1,a_2,{\ldots}a_p\} are\ equivalent$ 

思路:

处理出每一位左边第一个比它小的下标,然后相同的话可取,不同不可取。

假如当前处理$a_i$,(也就是$\{a_1,a_2,{\ldots}a_{i-1}\}$满足条件),假设比它第一个小的是$last[i]$,那么$last[i]$右边的$RMQ$一定是$a_i$,这样的话,$last[i]$左边的$RMQ$一定与新数无关,因为仅仅$last[i]$处就已经比$a_i$小了。

可以利用单调栈求每一位左边第一个比它小的下标

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 
 5 int n,a[maxn],b[maxn],ida[maxn],idb[maxn];
 6 
 7 stack<pair<int,int> > s;
 8 
 9 int main() {
10     while(~scanf("%d",&n)) {
11         s.push(make_pair(-1,-1));
12         for(int i=0;i<n;i++) {
13             scanf("%d",&a[i]);
14             while(!s.empty()&&s.top().first>a[i]) s.pop();
15             ida[i]=s.top().second;
16             s.push(make_pair(a[i],i));
17         }
18         while(!s.empty()) s.pop();
19         s.push(make_pair(-1,-1));
20         for(int i=0;i<n;i++) {
21             scanf("%d",&b[i]);
22             while(!s.empty()&&s.top().first>b[i]) s.pop();
23             idb[i]=s.top().second;
24             s.push(make_pair(b[i],i));
25         }
26         int cur=0;
27         while(cur<n) {
28             if(ida[cur]==idb[cur]) cur++;
29             else break;
30         }
31         printf("%d\n",cur);
32     }
33     return 0;
34 }

 

J:Fraction Comparision

题意:判断$\frac{x}a$与$\frac{y}b$的大小关系

  • $0{\leq}x,y{\leq}10^{18}$
  • $1{\leq}a,b{\leq}10^9$

思路:

  • 不能用浮点数判断(精度不够?)
  • 把$\frac{x}a$写成${\lfloor}{\frac{x}a}{\rfloor}+{x\%a}$ 先比较整数部分,再交叉相乘比较分数
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 void out(ll x,ll y) {
 6     if(x==y)  puts("=");
 7     else if(x>y) puts(">");
 8     else puts("<");
 9 }
10 
11 
12 int main() {
13     ll x,a,y,b;
14     while(~scanf("%lld%lld%lld%lld",&x,&a,&y,&b)) {
15         ll A=x/a;
16         ll B=y/b;
17         x%=a;
18         y%=b;
19         if(A!=B) out(A,B);
20         else out(x*b,y*a);
21     }
22     return 0;
23 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值