zoukankan      html  css  js  c++  java
  • 栅栏

    问题描述
    家有一条栅栏,由n个木板顺序组成,第i个木板的高度是Ai。现在小镇上流行在栅栏
    上画矩形,所以小v也要在自家的栅栏上画。若要在区间 [x,x+k-1] 这个区间画一个宽度为
    k的矩形 (1≤x≤n-k+1) ,为了美观,高度一定是这个区间里高度最低的木板。现在小v心中
    有m个理想的宽度,第i个为Ki,(Ki与Kj之间可能一样)。他想知道对于每个Ki,其矩形高度的
    期望。
    输入格式
    第一行一个整数n,表示木板的数目。
    第二行有n个正整数,第i个数表示第i个木板的高度。
    第三行一个整数m,表示理想宽度的数目。
    第四行有m个正整数,第i个数表示
    心中理想的第i个宽度Ki。
    输出格式
    输出m行实数,第i行表示宽度为Ki的矩形高度的期望。答案保留5位小数。
    样例输入输出
    样例输入1
    3
    3 2 1
    4
    1 2 3 1样例输出1
    2.00000
    1.50000
    1.00000
    2.00000
    限制与约定
    对于100%的数据,

    n<=1e6,m<=1e6,1<=Ai<=1e9,1<=Ki<=n

    题解:

    显然处理出L[i],R[i]表示左右第一个比i小的数,显然这个区间内跨越i的都是属于i的贡献

    我们就处理L[i],R[i]之间端点,枚举i-L[i] 或 i-R[i] 显然处理较小的那个,然后差分加减即可

    复杂度O(nlogn) 开始还以为和暴力是一样的..........................................................................

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #define ls (node<<1)
      8 #define rs (node<<1|1)
      9 using namespace std;
     10 typedef long long ll;
     11 const int N=1000005,INF=2e9;
     12 int gi(){
     13     int str=0;char ch=getchar();
     14     while(ch>'9' || ch<'0')ch=getchar();
     15     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
     16     return str;
     17 }
     18 int a[N],n,m,ques[N],b[N],c[N],num=0,L[N],R[N];ll ans[N];
     19 namespace Deal1{
     20     int Tree[N<<2];
     21     void build(int l,int r,int node){
     22         if(l==r){
     23             Tree[node]=a[l];
     24             return ;
     25         }
     26         int mid=(l+r)>>1;
     27         build(l,mid,ls);build(mid+1,r,rs);
     28         Tree[node]=Tree[ls]<Tree[rs]?Tree[ls]:Tree[rs];
     29     }
     30     int query(int l,int r,int node,int sa,int se){
     31         if(l>se || r<sa)return INF;
     32         if(sa<=l && r<=se)return Tree[node];
     33         int mid=(l+r)>>1;
     34         int q1=query(l,mid,ls,sa,se),q2=query(mid+1,r,rs,sa,se);
     35         return q1<q2?q1:q2;
     36     }
     37     void main(){
     38         int k,tmp;
     39         build(1,n,1);
     40         for(int i=1;i<=num;i++){
     41             k=c[i];
     42             for(int j=1;j+k-1<=n;j++){
     43                 tmp=query(1,n,1,j,j+k-1);
     44                 ans[k]+=tmp;
     45             }
     46         }
     47         double ret;
     48         for(int i=1;i<=m;i++){
     49             ret=(double)ans[ques[i]]/(n-ques[i]+1);
     50             printf("%.5lf
    ",ret);
     51         }
     52    }
     53 }
     54 namespace Deal2{
     55     int L[N],R[N],q[N];ll ans[N];
     56     void prework(){
     57         int r=1;q[0]=0;
     58         for(int i=1;i<=n;i++){
     59             while(1<=r && a[i]<a[q[r]])r--;
     60             L[i]=q[r]+1;q[++r]=i;
     61         }
     62         r=0;q[0]=n+1;
     63         for(int i=n;i>=1;i--){
     64             while(1<=r && a[i]<=a[q[r]])r--;
     65             R[i]=q[r]-1;q[++r]=i;
     66         }
     67     }
     68     void Getanswer(){
     69         int l,r;
     70         for(int i=1;i<=n;i++){
     71             l=i-L[i]+1;r=R[i]-i+1;
     72             if(l>r)swap(l,r);
     73             for(int j=1;j<=l;j++)
     74                 ans[j]+=a[i],ans[j+r]-=a[i];
     75         }
     76             for(int i=1;i<=c[num];i++)ans[i]+=ans[i-1];
     77     }
     78     void main(){
     79         prework();
     80         Getanswer();
     81         double ret;
     82         for(int i=1;i<=m;i++){
     83             ret=(double)(ans[ques[i]])/(n-ques[i]+1);
     84             printf("%.5lf
    ",ret);
     85         }
     86     }
     87 }
     88 void work(){
     89     n=gi();
     90     for(int i=1;i<=n;i++)a[i]=gi();
     91       m=gi();
     92       for(int i=1;i<=m;i++)ques[i]=b[i]=gi();
     93       sort(b+1,b+m+1);
     94       for(int i=1;i<=m;i++)if(b[i]!=b[i+1])c[++num]=b[i];
     95     if(n<=2000)Deal1::main();
     96     else
     97     Deal2::main();
     98 }
     99 int main()
    100 {
    101     freopen("fence.in","r",stdin);
    102     freopen("fence.out","w",stdout);
    103     work();
    104     return 0;
    105 }
  • 相关阅读:
    如何通过命令行窗口查看sqlite数据库文件
    eclipse自动补全的设置
    文本装饰
    注释和特殊符号
    文本装饰
    网页背景
    通过ArcGIS Server admin 查看和删除已注册的 Web Adaptor
    通过 ArcGIS Server Manager 查看已安装的 Web Adaptor
    通过 ArcGIS Server Manager 验证 DataStore
    Windows上安装ArcGIS Enterprise——以 Windows Server 2012 R2上安装 ArcGIS 10.8为例
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7202141.html
Copyright © 2011-2022 走看看