zoukankan      html  css  js  c++  java
  • 洛谷3707 [SDOI2017] 相关分析 【线段树】

    分析:

    化简一下就行了,注意一下平方和公式的运用以及精度的误差。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 105000;
      5 
      6 int n,m;
      7 
      8 int x[maxn],y[maxn];
      9 
     10 struct node{
     11     int lazx1,lazx2,lazy1,lazy2;
     12     double multi,sumx,sumy,sqr;
     13 }T[maxn<<2];
     14 
     15 long long ump(int l,int r){
     16     return (1ll*r*(r+1)*(2*r+1)-1ll*(l-1)*l*(2*l-1))/6;
     17 }
     18 
     19 void fugai(int now,int tl,int tr,int s,int t){
     20     T[now].lazx2 = T[now].lazy2 = 0;
     21     T[now].lazx1 = s; T[now].lazy1 = t;
     22     T[now].sumx = 1ll*((s+tl)+(s+tr))*(tr-tl+1)/2;
     23     T[now].sumy = 1ll*((t+tl)+(t+tr))*(tr-tl+1)/2;
     24     T[now].sqr = 1ll*(tr-tl+1)*s*s+1ll*s*(tl+tr)*(tr-tl+1)+ump(tl,tr);
     25     T[now].multi=1ll*(tr-tl+1)*s*t+1ll*(s+t)*(tl+tr)*(tr-tl+1)/2+ump(tl,tr);
     26 }
     27 
     28 void add(int now,int tl,int tr,int s,int t){
     29     T[now].lazx2+=s;T[now].lazy2 += t;
     30     T[now].multi+=1ll*s*T[now].sumy+1ll*t*T[now].sumx+1ll*s*t*(tr-tl+1);
     31     T[now].sqr +=1ll*s*s*(tr-tl+1)+2ll*s*T[now].sumx;
     32     T[now].sumx += 1ll*s*(tr-tl+1); T[now].sumy += 1ll*t*(tr-tl+1);
     33 }
     34 
     35 void push_up(int now){
     36     T[now].multi = T[now<<1].multi+T[now<<1|1].multi;
     37     T[now].sumx = T[now<<1].sumx+T[now<<1|1].sumx;
     38     T[now].sumy = T[now<<1].sumy+T[now<<1|1].sumy;
     39     T[now].sqr = T[now<<1].sqr+T[now<<1|1].sqr;
     40 }
     41 
     42 void push_down1(int now,int tl,int tr){
     43     int mid = (tl+tr)/2;
     44     fugai(now<<1,tl,mid,T[now].lazx1,T[now].lazy1);
     45     fugai(now<<1|1,mid+1,tr,T[now].lazx1,T[now].lazy1);
     46     T[now].lazx1 = T[now].lazy1 = 123456;
     47 }
     48 
     49 void push_down2(int now,int tl,int tr){
     50     int mid = (tl+tr)/2;
     51     add(now<<1,tl,mid,T[now].lazx2,T[now].lazy2);
     52     add(now<<1|1,mid+1,tr,T[now].lazx2,T[now].lazy2);
     53     T[now].lazx2 = T[now].lazy2 = 0;
     54 }
     55 
     56 void read(){
     57     scanf("%d%d",&n,&m);
     58     for(int i=1;i<=n;i++)scanf("%d",&x[i]);
     59     for(int i=1;i<=n;i++) scanf("%d",&y[i]);
     60 }
     61 
     62 node merge(node ai,node bi){
     63     return (node){0,0,0,0,ai.multi+bi.multi,ai.sumx+bi.sumx,ai.sumy+bi.sumy,ai.sqr+bi.sqr};
     64 }
     65 
     66 void build_tree(int now,int l,int r){
     67     if(l == r){
     68     T[now].lazx1 = T[now].lazy1 = 123456;
     69     T[now].multi = 1ll*x[l]*y[l];
     70     T[now].sumx = x[l];T[now].sumy = y[l];
     71     T[now].sqr = 1ll*x[l]*x[l];
     72     }else{
     73     int mid = (l+r)/2;
     74     build_tree(now<<1,l,mid);
     75     build_tree(now<<1|1,mid+1,r);
     76     T[now].lazx1 = T[now].lazy1 = 123456;
     77     push_up(now);
     78     }
     79 }
     80 
     81 node Query(int now,int tl,int tr,int l,int r){
     82     if(tl >= l && tr <= r){return T[now];}
     83     if(tl > r || tr < l){return (node){0,0,0,0,0,0,0,0};}
     84     if(T[now].lazx1<=maxn||T[now].lazy1<=maxn) push_down1(now,tl,tr);
     85     if(T[now].lazx2||T[now].lazy2) push_down2(now,tl,tr);
     86     int mid = (tl+tr)/2;
     87     node ans = merge(Query(now<<1,tl,mid,l,r),Query(now<<1|1,mid+1,tr,l,r));
     88     push_up(now);
     89     return ans;
     90 }
     91 
     92 void Modify1(int now,int tl,int tr,int l,int r,int s,int t){
     93     if(tl >= l && tr <= r){
     94     add(now,tl,tr,s,t);
     95     return;
     96     }
     97     if(tl > r || tr < l){return;}
     98     if(T[now].lazx1<=maxn||T[now].lazy1<=maxn) push_down1(now,tl,tr);
     99     if(T[now].lazx2||T[now].lazy2) push_down2(now,tl,tr);
    100     int mid = (tl+tr)/2;
    101     Modify1(now<<1,tl,mid,l,r,s,t);
    102     Modify1(now<<1|1,mid+1,tr,l,r,s,t);
    103     push_up(now);
    104 }
    105 
    106 void Modify2(int now,int tl,int tr,int l,int r,int s,int t){
    107     if(tl >= l && tr <= r){
    108     fugai(now,tl,tr,s,t);
    109     return;
    110     }
    111     if(tl > r || tr < l){return;}
    112     if(T[now].lazx1<=maxn||T[now].lazy1<=maxn) push_down1(now,tl,tr);
    113     if(T[now].lazx2||T[now].lazy2) push_down2(now,tl,tr);
    114     int mid = (tl+tr)/2;
    115     Modify2(now<<1,tl,mid,l,r,s,t);
    116     Modify2(now<<1|1,mid+1,tr,l,r,s,t);
    117     push_up(now);
    118 }
    119 
    120 void work(){
    121     build_tree(1,1,n);
    122     for(int i=1;i<=m;i++){
    123     int cas; scanf("%d",&cas);
    124     if(cas == 1){
    125         int l,r; scanf("%d%d",&l,&r);
    126         node forw = Query(1,1,n,l,r);
    127         double pjx = 1.0*forw.sumx/(r-l+1),pjy = 1.0*forw.sumy/(r-l+1);
    128         double res=forw.multi+pjx*pjy*(r-l+1)-pjx*forw.sumy-pjy*forw.sumx;
    129         res /= 1.0*(forw.sqr+pjx*pjx*(r-l+1)-2.0*pjx*forw.sumx);
    130         printf("%.10lf
    ",res);
    131     }else{
    132         if(cas == 2){
    133         int l,r,s,t; scanf("%d%d%d%d",&l,&r,&s,&t);
    134         Modify1(1,1,n,l,r,s,t);
    135         }else{
    136         int l,r,s,t; scanf("%d%d%d%d",&l,&r,&s,&t);
    137         Modify2(1,1,n,l,r,s,t);
    138         }
    139     }
    140     }
    141 }
    142 
    143 int main(){
    144     read();
    145     work();
    146     return 0;
    147 }
  • 相关阅读:
    Python 抓取 iphone13 pro 线下店供货信息并发送到钉钉机器人,最后设置为定时任务
    crontab 解决 mac 下通过 crontab 设置了 Python 脚本的定时任务却无法运行
    Python 好用第三方库 isort
    Python 接入钉钉机器人
    Effective Python(2) 遵循 PEP 8 风格指南
    fastapi(65) 路由函数指定了 response_model,在返回自定义 JSONResponse 时, 不会限制它返回的数据结构
    Mysql 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?
    Effective Python(1) 查询自己使用的Python版本
    fastapi(66) 修改 uvicorn 的日志格式
    重要通知!重要通知!不是广告!不是广告!
  • 原文地址:https://www.cnblogs.com/Menhera/p/9148143.html
Copyright © 2011-2022 走看看