[线段树][读入优化][玄学加速]借教室 noip

借教室

首先,这是一道水题,线段树直接敲起




但是!!!!!!

如果,你只是简单地敲了一份线段树,你会发现,你会卡两个至少两个点!!!

因为读入会被卡!

于是,你可以使用getchar()来进行玄学加速……

vijos上加速近1000ms!!!!!以下是 借教室 AC代码

#include 
const int maxind = 1000001;
int sum=-1;
int a[maxind]={0};
struct nodes{
    int flag;
    int min;
    int max;
    nodes(void){
        this->flag=0;
        this->min=0;
        this->max=0;
    }
};
nodes sumsTree[maxind * 4 + 10]; 
inline void read(int&x){  //玄学加速的开始
    char ch=getchar();
    x=0;
    while (ch>'9'||ch<'0')
        ch=getchar();
    while (ch<='9'&&ch>='0'){
        x*=10;
        x+=ch-'0';
        ch=getchar();
    }
    return ;
}
inline int min(int a,int b){
    return (aint max(int a,int b){
    return (a>b)?a:b;
}
inline void pushdown(int node){
    const int lc=(node<<1),rc=(node<<1)|1;
    int flag=sumsTree[node].flag;
    sumsTree[lc].flag+=flag;
    sumsTree[rc].flag+=flag;
    sumsTree[lc].max+=flag;
    sumsTree[lc].min+=flag; 
    sumsTree[rc].max+=flag;
    sumsTree[rc].min+=flag;
    return ;
} 
void build(int node, int begin, int end)    
{   
    if (begin == end){
        sumsTree[node].max = a[begin];
        sumsTree[node].min = a[begin];
    }
    else  
    {     
        int t=(begin+end)>>1;
        build((node<<1), begin, t);  
        build(node*2|1, t+1, end);
        sumsTree[node].min=min(sumsTree[(node<<1)].min,sumsTree[(node<<1)|1].min);
        sumsTree[node].max=max(sumsTree[(node<<1)].max,sumsTree[(node<<1)|1].max);
    }
}  
void add(int node,int begin,int end,const int left,const int right,const int num){
    if (begin>right||endreturn ;
    int t=(begin+end)>>1;
    const int lc=(node<<1),rc=(node<<1)|1;
    nodes& cur=sumsTree[node];
    if (begin>=left&&end<=right)
    {
        cur.flag+=num;
        cur.max+=num;
        cur.min+=num;
        return ;
    }
    pushdown(node);
    cur.flag=0;
    add(lc,begin,t,left,right,num);
    add(rc,t+1,end,left,right,num);
    cur.max=max(sumsTree[lc].max,sumsTree[rc].max);
    cur.min=min(sumsTree[lc].min,sumsTree[rc].min);
    return ;
}
int query(int node,int begin,int end,const int left,const int right,const int num){
    if (begin>right||endreturn 0;
    int t=(begin+end)>>1;
    const int lc=(node<<1),rc=(node<<1)|1;
    nodes &cur=sumsTree[node]; 
    if (begin>=left&&end<=right)
    {
        if(cur.maxreturn 0;
        if (cur.min>=num) {return end-begin+1;}
        if (begin!=end){
            pushdown(node);
            return query(lc,begin,t,left,right,num)+query(rc,t+1,end,left,right,num);
        }

    }
    pushdown(node);
    cur.flag=0;
    return query(lc,begin,t,left,right,num)+query(rc,t+1,end,left,right,num);
}
int main(void)  
{
    int n,m;
    read(n);read(m);
//  scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        read(a[i]);
    build(1,1,n);
    for (int i=1;i<=m;i++)
    {
        char ch=getchar();
        int from,to,ds;
        while (ch!='Q'&&ch!='A')
            ch=getchar();
        read(from);read(to);read(ds);
        if (ch=='Q'){
            add(1,1,n,from,to,ds);
        }
//      else {
            printf("%d\n",query(1,1,n,from,to,ds));
//      }
    }
    return 0;  
}   

因为很重要所以贴两遍

inline void read(int&x){  //玄学加速的开始
    char ch=getchar();
    x=0;
    while (ch>'9'||ch<'0')
        ch=getchar();
    while (ch<='9'&&ch>='0'){
        x*=10;
        x+=ch-'0';
        ch=getchar();
    }
    return ;
}

你可能感兴趣的:(算法)