• suoi37 清点更多船只 (卡空间线段树)


    sbw巨佬的卡空间方法,把线段树的叶节点只记到长度为16的区间,然后在叶节点上暴力修改查询,这样点数是$frac{N}{8}$的,可以过...

    orz

      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=(1<<20),maxp=(1<<18)+10;
      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 ll sum[maxp],v[maxn],laz[maxp];
     16 int N,M;
     17 
     18 inline void update(int p,int l,int r){
     19     if(r-l+1<=16){    
     20         sum[p]=0;
     21         for(int i=l;i<=r;i++){
     22             sum[p]+=v[i];
     23         }
     24     }else{
     25         sum[p]=sum[p<<1]+sum[p<<1|1];
     26     }
     27 }
     28 inline void deal(int p,int l,int r,ll z){
     29     if(r-l+1<=16){
     30         for(int i=l;i<=r;i++){
     31             v[i]+=z,sum[p]+=z;
     32         }
     33     }else sum[p]+=z*(r-l+1);
     34 }
     35 
     36 inline void pushdown(int p,int l,int r){
     37     if(!laz[p]||r-l+1<=16) return;
     38     int a=p<<1,b=p<<1|1,m=l+r>>1;
     39     deal(a,l,m,laz[p]),deal(b,m+1,r,laz[p]);
     40     laz[a]+=laz[p],laz[b]+=laz[p];
     41     laz[p]=0;
     42 }
     43 
     44 void build(int p,int l,int r){
     45     if(r-l+1<=16) update(p,l,r);
     46     else{
     47         int m=l+r>>1;
     48         build(p<<1,l,m);
     49         build(p<<1|1,m+1,r);
     50         // printf("!%d %d %d
    ",p,l,r);
     51         update(p,l,r);
     52     }
     53 }
     54 
     55 ll query(int p,int l,int r,int x,int y){
     56     // printf("~~%d %d %d %d %d
    ",p,l,r,x,y);
     57     pushdown(p,l,r);
     58     if(x<=l&&r<=y) return sum[p];
     59     if(r-l+1<=16){
     60         ll re=0;
     61         for(int i=x;i<=y;i++) re+=v[i];
     62         return re;
     63     }
     64     int m=l+r>>1;ll re=0;
     65     if(x<=m) re=query(p<<1,l,m,x,min(m,y));
     66     if(y>=m+1) re+=query(p<<1|1,m+1,r,max(x,m+1),y);
     67     return re;
     68 }
     69 
     70 void add(int p,int l,int r,int x,int y,ll z){
     71     // printf("!!%d %d %d %d %d
    ",p,l,r,x,y);
     72     pushdown(p,l,r);
     73     if(r-l+1<=16){
     74         for(int i=x;i<=y;i++)
     75             v[i]+=z,sum[p]+=z;
     76     }else if(x<=l&&r<=y){
     77         deal(p,l,r,z);
     78         laz[p]+=z;
     79     }else{
     80         int m=l+r>>1;
     81         if(x<=m) add(p<<1,l,m,x,min(m,y),z);
     82         if(y>=m+1) add(p<<1|1,m+1,r,max(m+1,x),y,z);
     83         update(p,l,r);
     84     }
     85 }
     86 
     87 int main(){
     88     //freopen("","r",stdin);
     89     int i;
     90     N=rd(),M=rd();
     91     for(i=1;i<=N;i++)
     92         v[i]=rd();
     93     N=1<<((int)log2(N)+1);
     94     build(1,1,N);
     95     for(i=1;i<=M;i++){
     96         char s[10];
     97         scanf("%s",s);
     98         int l=rd(),r=rd();
     99         if(s[1]=='d'){
    100             int d=rd();
    101             add(1,1,N,l,r,d);
    102         }else printf("%lld
    ",query(1,1,N,l,r));
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    windows下使用mingw编译出ffplay(简化版)
    Linux中查看GNOME版本号
    Linux操作系统入门学习总结(2015.10)
    c++11并发机制
    CentOS 7修改管理员密码
    windows下批量杀死进程
    ffmpeg抓屏输出的设置
    User-Defined-Literal自定义字面量
    GitHub支持的Markdown语法 GitHub Flavored Markdown
    c++11支持类数据成员的初始化
  • 原文地址:https://www.cnblogs.com/Ressed/p/9794670.html
Copyright © 2020-2023  润新知