zoukankan      html  css  js  c++  java
  • 各种板子

    线段树

    区间修改,区间求和

    https://www.luogu.org/problemnew/show/P3372

    代码

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=100000+10;
    
    ll a[maxn];
    ll add[maxn<<2],tree[maxn<<2];
    
    void pushup(int rt){
         tree[rt]=tree[rt<<1]+tree[rt<<1|1];
    }
    
    void build(int l,int r,int rt){
         if(l==r){
            tree[rt]=a[l];
            return ;
         }
         int mid=(l+r)>>1;
         build(l,mid,rt<<1);
         build(mid+1,r,rt<<1|1);
         pushup(rt);
    }
    
    void pushdown(int rt,int ln,int rn){
         if(add[rt]){
            add[rt<<1]+=add[rt];
            add[rt<<1|1]+=add[rt];
            tree[rt<<1]+=add[rt]*ln;
            tree[rt<<1|1]+=add[rt]*rn;
            add[rt]=0;
         }
    }
    
    void update(int l,int r,int rt,int L,int R,int c){
         if(l>=L&&r<=R){
            add[rt]+=c;
            tree[rt]+=c*(r-l+1);
            return ;
         }
         int mid=(l+r)>>1;
         pushdown(rt,mid-l+1,r-mid);
         if(L<=mid) update(l,mid,rt<<1,L,R,c);
         if(R>mid) update(mid+1,r,rt<<1|1,L,R,c);
         pushup(rt);
    }
    
    ll ask(int l,int r,int rt,int L,int R){
       if(l>=L&&r<=R){
        return tree[rt];
       }
       int mid=(l+r)>>1;
       pushdown(rt,mid-l+1,r-mid);
       ll ans=0;
       if(L<=mid) ans+=ask(l,mid,rt<<1,L,R);
       if(R>mid) ans+=ask(mid+1,r,rt<<1|1,L,R);
       return ans;
    }
    
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        build(1,n,1);
        int op,x,y,k;
        while(m--){
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&x,&y,&k);
                update(1,n,1,x,y,k);
            }
            else {
                scanf("%d%d",&x,&y);
                printf("%lld
    ",ask(1,n,1,x,y));
            }
        }
    return 0;
    }

    二分

     二分,第一个大于x

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int maxn=1000;
    
    int a[maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int l=1;
        int r=n;
        while(l<=r){
            int mid=(l+r)>>1;
            if(a[mid]>5){若要查找最后一个小于x的改为>=,输出r;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d ",l);
    return 0;
    }

    可以这样理解,查找大于等于的,判断那里就是大于等于,查找小于等于的判断那里是大于


    二维前缀和

    垃圾炸弹

    https://www.lydsy.com/JudgeOnline/problem.php?id=1218

    代码

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn=5050;
    
    int sum[maxn][maxn];
    
    int main(){
        int n,r;
        int x,y,w;
        scanf("%d%d",&n,&r);
        for (int i=1;i<=n;i++){
            scanf("%d%d%d",&x,&y,&w);
            sum[x+1][y+1]=w;
        }
        for (int i=1;i<=5001;i++) sum[1][i]=sum[1][i-1]+sum[1][i];
        for (int i=1;i<=5001;i++) sum[i][1]=sum[i-1][1]+sum[i][1];
        for (int i=2;i<=5001;i++){
            for (int j=2;j<=5001;j++){
                sum[i][j]=sum[i-1][j]+sum[i][j-1]+sum[i][j]-sum[i-1][j-1];
            }
        }
    
        int ans=0;
        for (int i=r;i<=5001;i++){
            for (int j=r;j<=5001;j++){
                ans=max(ans,sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]);
            }
        }
        printf("%d",ans);
    return 0;
    }

    前缀和

    https://www.luogu.org/recordnew/show/11207133

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn=100000+10;
    
    ll sum[maxn];
    
    int main(){
        int n,k,y;
        scanf("%d%d",&n,&k);
        for (int i=1;i<=n;i++){
            scanf("%d",&y);
            sum[i]=sum[i-1]+y;
        }
        ll ans=0;
        for (int i=k;i<=n;i++) ans+=(sum[i]-sum[i-k]);
        printf("%lld",ans);
    return 0;
    }

    快速幂

    https://www.luogu.org/problemnew/show/P1226

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    typedef long long ll;
    ll mod;
    
    ll quickmod(ll a,ll b,ll mod){
       ll ans=1%mod;
       for (;b;b>>=1){
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
       }
       return ans%mod;
    }
    
    int main(){
        ll a,b;
        scanf("%lld%lld%lld",&a,&b,&mod);
        printf("%lld^%lld mod %lld=%lld",a,b,mod,quickmod(a,b,mod));
    return 0;
    }
  • 相关阅读:
    从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇
    Intent----android中的伟大邮差
    一步一步掌握线程机制(五)---等待与通知机制
    一步一步掌握线程机制(四)---同步方法和同步块
    一步一步掌握线程机制(三)---synchronized和volatile的使用
    利用单例模式解决全局访问问题
    一步一步掌握java的线程机制(二)----Thread的生命周期
    一步一步掌握java的线程机制(一)----创建线程
    如何快速学会android的四大基础----Service篇
    前端工程师必备实用网站
  • 原文地址:https://www.cnblogs.com/lmjer/p/9715575.html
Copyright © 2011-2022 走看看