FunctionTime Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 4673 Accepted Submission(s): 1461 Problem Description The shorter, the simpler. With this problem, you should be convinced of this truth.
Input There are multiple test cases.
Output For each query(l,r) , output F(l,r) on one line.
Sample Input
1 3 2 3 3 1 1 3
Sample Output
2
Source 2016 ACM/ICPC Asia Regional Dalian Online
Recommend wange2014 |
求Al%....%AR。
预处理出每一个位置的X第一个小于等于X的位置。找到后退出。
查询时从区间i=l+1跳动到pos[i],然后要小于r即可。
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 100000+6;
const ll mod=10007;
int n,k,m;
int a[maxn];
int pos[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n; i++)
{
int tmp=n+1;
for(int j=i+1; j<=n; j++)
{
if(a[j]<=a[i])
{
tmp=j;
break;
}
}
pos[i]=tmp;
}
int m;
scanf("%d",&m);
while(m--)
{
int l,r;
scanf("%d %d",&l,&r);
int ans=a[l];
for(int i=l+1;i<=r;i=pos[i])
{
int v=a[i];
ans%=v;
}
printf("%d\n",ans);
}
}
}
线段树做法:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mxn=200010;
int n,a[mxn];
int mm[mxn],lc[mxn],rc[mxn],t;
int bu(int l,int r){
int x=++t;
if(l==r){
mm[x]=a[l];
return x;
}
int mi=(l+r)/2;
lc[x]=bu(l,mi);
rc[x]=bu(mi+1,r);
mm[x]=min(mm[lc[x]],mm[rc[x]]);
return x;
}
int ql,qr;
int que(int x,int l,int r,int v){
if(mm[x]>v) return 0;
if(l==r) return l;
int mi=(l+r)/2,a;
if(ql<=mi){
a=que(lc[x],l,mi,v);
if(a) return a;
}
if(qr>mi) return que(rc[x],mi+1,r,v);
return 0;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
t=0;
bu(1,n);
int m;
scanf("%d",&m);
while(m--){
scanf("%d%d",&ql,&qr);
int nw=a[ql];
ql=ql+1;
while(ql<=qr){
int x=que(1,1,n,nw);
if(!x) break;
ql=x+1;
nw%=a[x];
}
printf("%d\n",nw);
}
}
return 0;
}
本文介绍了一种快速查询算法的优化方案,通过预处理数组找到每个位置的下一个小于等于当前值的位置,实现对区间函数F(l,r)的高效计算。提供了两种实现方式,一种是直接遍历查找,另一种是使用线段树进行优化,显著提高了查询效率。

被折叠的 条评论
为什么被折叠?



