因为原序列是排列好了的,那么只要看一下给出的两个区间相交的情况,然后分类讨论一下,O(1)输出。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } } const int maxn=100010; int T,n,m,a[maxn]; int get(int l1,int r1,int l2,int r2 ,int x) { if(l2>r1) { if(r1-l1+1>=x) return a[l1+x-1]; else return a[l2+x-(r1-l1+1)-1]; } else if(r2<=r1) { if(l2-l1>=x) return a[l1+x-1]; else if(2*(r2-l2+1)+l2-l1>=x) return a[l2+(x-(l2-l1)-1)/2]; else return a[r2+1+x-(2*(r2-l2+1)+l2-l1)-1]; } else { if(l2-l1>=x) return a[l1+x-1]; else if(2*(r1-l2+1)+l2-l1>=x) return a[l2+(x-(l2-l1)-1)/2]; else return a[r1+1+x-(2*(r1-l2+1)+l2-l1)-1]; } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) { int l1,r1,l2,r2; scanf("%d%d%d%d",&l1,&r1,&l2,&r2); if(l1>l2) { swap(l1,l2); swap(r1,r2); } if((r1-l1+1+r2-l2+1)%2==1) { printf("%.1lf\n",1.0*get(l1,r1,l2,r2,(r1-l1+1+r2-l2+1)/2+1)); } else { double num1=1.0*get(l1,r1,l2,r2,(r1-l1+1+r2-l2+1)/2); double num2=1.0*get(l1,r1,l2,r2,(r1-l1+1+r2-l2+1)/2+1); printf("%.1lf\n",1.0*(num1+num2)/2.0); } } } return 0; }
时间: 2024-10-11 01:42:07