首页 > 代码库 > nyoj 119
nyoj 119
士兵杀敌(三)
时间限制:2000 ms | 内存限制:65535 KB
难度:5
- 描述
南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。
所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。
现在,请你写一个程序,帮小工回答南将军每次的询问吧。
注意,南将军可能询问很多次。
- 输入
- 只有一组测试数据
第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1<N<=100000,1<Q<=1000000)
随后的一行有N个整数Vi(0<=Vi<100000000),分别表示每个人的杀敌数。
再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。 - 输出
- 对于每次询问,输出第m号士兵到第n号士兵之间所有士兵杀敌数的最大值与最小值的差。
- 样例输入
5 21 2 6 9 31 22 4
- 样例输出
17
- 来源
- 经典改编
- 上传者
- 张云聪
/*f[i][j]=max(f[i][j-1],f[i+1<<(j-1)][j-1])*/#include<iostream>#include<cstdio>#include<cmath>using namespace std;#define max(a,b) a>b?a:b#define min(a,b) a>b?b:a#define maxn 100010int n,q;int a[maxn],maxsum[maxn][20],minsum[maxn][20];int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { maxsum[i][0]=a[i]; minsum[i][0]=a[i]; } for(int j=1;j<20;j++) for(int i=1;i<n;i++) if(i+(1<<(j-1))<=n) { maxsum[i][j]=max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]); minsum[i][j]=min(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]); } for(int i=1;i<=q;i++) { int m,n; scanf("%d%d",&m,&n); int k=(int)(log(n-m+1.0)/log(2.0)); int maxi=max(maxsum[m][k],maxsum[n-(1<<k)+1][k]); int mini=min(minsum[m][k],minsum[n-(1<<k)+1][k]); printf("%d\n",maxi-mini); } return 0;}运算符注意了。。。
nyoj 119
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。