zoukankan      html  css  js  c++  java
  • luogu3707 相关分析 (线段树)

    把式子展开以后会发现,可以用线段树维护$x,y,x*y,x^2$分别的区间和

    然后操作有区间加和区间修改

    这个pushdown的时候,如果改和加的标记同时存在,那一定是先改再加,要不然加的标记已经被清掉了

    所以在pushdown的时候,如果有改的标记,要把孩子的加的标记清掉

    然后注意细节就行了(用*传数组 然后在函数里改了的话 它真的会改的 怎么就意识不到呢...)

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 using namespace std;
      5 typedef long long ll;
      6 const int maxn=1e5+10,inf=1e9;
      7 
      8 inline ll rd(){
      9     ll x=0;char c=getchar();int neg=1;
     10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     12     return x*neg;
     13 }
     14 
     15 struct Node{
     16     double x,y,xy,x2;
     17     int l,r;
     18     Node(double a=0,double b=0,double c=0,double d=0,int e=0,int f=0){
     19         x=a,y=b,xy=c,x2=d,l=e,r=f;
     20     }
     21 }tr[maxn*4];
     22 double laz[maxn*4][4];
     23 int ch[maxn*4][2],pct,X[maxn],Y[maxn];
     24 int N,M;
     25 
     26 Node operator + (Node a,Node b){
     27     Node p;
     28     p.l=a.l,p.r=b.r;
     29     p.x=a.x+b.x,p.y=a.y+b.y;
     30     p.xy=a.xy+b.xy,p.x2=a.x2+b.x2;
     31     return p;
     32 }
     33 
     34 inline void deal(Node &p,double *v){
     35     int r=p.r,l=p.l;
     36     if(v[2]!=-inf){
     37         p.x=p.y=1ll*(p.r+p.l)*(p.r-p.l+1)/2;
     38         p.xy=p.x2=(1ll*r*(r+1)*(2*r+1))/6-(1ll*(l-1)*l*(2*l-1))/6;
     39         v[0]+=v[2],v[1]+=v[3];
     40     }
     41     
     42     p.x2+=(p.r-p.l+1)*v[0]*v[0]+2*v[0]*p.x;
     43     p.xy+=v[0]*p.y+v[1]*p.x+(p.r-p.l+1)*v[0]*v[1];
     44     p.x+=(p.r-p.l+1)*v[0],p.y+=(p.r-p.l+1)*v[1];
     45     if(v[2]!=-inf) v[0]-=v[2],v[1]-=v[3];
     46 }
     47 
     48 inline void pushdown(int p){
     49     // return;
     50     if(!ch[p][0]) return;
     51     if(laz[p][0]==0&&laz[p][1]==0&&laz[p][2]==-inf) return;
     52     int a=ch[p][0],b=ch[p][1];
     53     if(laz[p][2]!=-inf){
     54         laz[a][0]=laz[a][1]=laz[b][0]=laz[b][1]=0;
     55         laz[a][2]=laz[p][2],laz[a][3]=laz[p][3];
     56         laz[b][2]=laz[p][2],laz[b][3]=laz[p][3];
     57     }
     58     laz[a][0]+=laz[p][0],laz[a][1]+=laz[p][1];
     59     laz[b][0]+=laz[p][0],laz[b][1]+=laz[p][1];
     60     
     61     deal(tr[a],laz[p]);
     62     deal(tr[b],laz[p]);
     63     laz[p][0]=laz[p][1]=0,laz[p][2]=laz[p][3]=-inf;
     64 }
     65 
     66 void build(int &p,int l,int r){
     67     p=++pct;
     68     laz[p][2]=laz[p][3]=-inf;
     69     if(l==r){
     70         tr[p]=Node(X[l],Y[l],1ll*X[l]*Y[l],1ll*X[l]*X[l],l,r);
     71     }else{
     72         int m=l+r>>1;
     73         build(ch[p][0],l,m);
     74         build(ch[p][1],m+1,r);
     75         tr[p]=tr[ch[p][0]]+tr[ch[p][1]];
     76     }
     77 }
     78 
     79 void query(int p,int l,int r,int x,int y,Node &q){
     80     pushdown(p);
     81     if(x<=l&&r<=y){
     82         if(!q.l) q=tr[p];
     83         else q=q+tr[p];
     84     }else{
     85         int m=l+r>>1;
     86         if(x<=m) query(ch[p][0],l,m,x,y,q);
     87         if(y>=m+1) query(ch[p][1],m+1,r,x,y,q);
     88     }
     89 }
     90 
     91 void add(int p,int l,int r,int x,int y,int s,int t){
     92     pushdown(p);
     93     if(x<=l&&r<=y){
     94         double v[5];
     95         v[0]=s,v[1]=t;v[2]=v[3]=-inf;
     96         deal(tr[p],v);
     97         laz[p][0]+=s,laz[p][1]+=t;
     98         pushdown(p);
     99     }else{
    100         int m=l+r>>1;
    101         if(x<=m) add(ch[p][0],l,m,x,y,s,t);
    102         if(y>=m+1) add(ch[p][1],m+1,r,x,y,s,t);
    103         tr[p]=tr[ch[p][0]]+tr[ch[p][1]];
    104     }
    105 }
    106 
    107 void change(int p,int l,int r,int x,int y,int s,int t){
    108     if(x<=l&&r<=y){
    109         double v[5];
    110         v[0]=v[1]=0,v[2]=s,v[3]=t;
    111         deal(tr[p],v);
    112         laz[p][0]=laz[p][1]=0,laz[p][2]=s,laz[p][3]=t;
    113         pushdown(p);
    114     }else{
    115         pushdown(p);    
    116         int m=l+r>>1;
    117         if(x<=m) change(ch[p][0],l,m,x,y,s,t);
    118         if(y>=m+1) change(ch[p][1],m+1,r,x,y,s,t);
    119         tr[p]=tr[ch[p][0]]+tr[ch[p][1]];
    120     }
    121 }
    122 
    123 int main(){
    124     int i,j,k;
    125     N=rd(),M=rd();
    126     for(i=1;i<=N;i++) X[i]=rd();
    127     for(i=1;i<=N;i++) Y[i]=rd();
    128     build(i,1,N);
    129     for(i=1;i<=M;i++){
    130         int a=rd(),b=rd(),c=rd();
    131         if(a==1){
    132             Node p;
    133             query(1,1,N,b,c,p);
    134             double xb=p.x/(c-b+1),yb=p.y/(c-b+1);
    135             double ans=0;
    136             ans=p.xy-xb*p.y-yb*p.x+xb*yb*(c-b+1);
    137             ans/=p.x2-2*xb*p.x+xb*xb*(c-b+1);
    138             printf("%.10lf
    ",ans);
    139         }else{
    140             int d=rd(),e=rd();
    141             if(a==2){
    142                 add(1,1,N,b,c,d,e);
    143             }else if(a==3){
    144                 change(1,1,N,b,c,d,e);
    145             }
    146         }
    147     }
    148     return 0;
    149 }
  • 相关阅读:
    【BNUOJ 4358】 左手定则
    【NOIP】关押罪犯
    【数算A】表达式·表达式树·表达式求值
    【POJ1679】The Unique MST
    【数算A】舰队、海域出击!
    【NOI2014】动物园
    【POJ1308】&&【HDU1272】Is It A Tree && 小希的迷宫
    【NOI2002】银河英雄传说
    html5之本地存储localStorage示例
    html5之应用缓存示例
  • 原文地址:https://www.cnblogs.com/Ressed/p/9794824.html
Copyright © 2011-2022 走看看