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 }