zoukankan      html  css  js  c++  java
  • 7.20模拟赛

    不管夜晚多么黑暗,黎明总是会到来。


    T1.BRS

    最大子段和,线段树维护区间sum,lmx,rmx,mx四个值。

    考虑最大子段和只能存在于左区间,右区间,或者跨越两个区间,合并即可。

    复杂度O(mlogn)

    (活生生看错题)

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const int MAXN=524288;
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    
    #define ls (cur<<1)
    #define rs (cur<<1|1)
    #define mid (l+r>>1)
    struct Node{
      Node(int x=0){sum=lmx=rmx=mx=x;}
      int sum,lmx,rmx,mx;
    }node[MAXN<<2];
    int a[MAXN];
    void pushup(int cur){
      node[cur].sum=node[ls].sum+node[rs].sum;
      node[cur].lmx=max(node[ls].lmx,node[ls].sum+node[rs].lmx);
      node[cur].rmx=max(node[rs].rmx,node[rs].sum+node[ls].rmx);
      node[cur].mx=max(node[ls].rmx+node[rs].lmx,max(node[ls].mx,node[rs].mx));
    }
    void build(int cur,int l,int r){
      if(l==r) {node[cur]=Node(a[l]);return;}
      build(ls,l,mid);build(rs,mid+1,r);
      pushup(cur);
    }
    void update(int x,int cur,int l,int r,int w){
      if(l==r) {node[cur]=Node(w);return;}
      if(x<=mid) update(x,ls,l,mid,w);
      else update(x,rs,mid+1,r,w);
      pushup(cur);
    }
    Node query(int L,int R,int cur,int l,int r){
      if(L<=l&&r<=R) return node[cur];
      Node lnode,rnode,ret;
      if(L<=mid) lnode=query(L,R,ls,l,mid);
      if(mid <R) rnode=query(L,R,rs,mid+1,r);
      if(!(L<=mid)) return rnode;
      if(!(mid <R)) return lnode;
      ret.sum=lnode.sum+rnode.sum;
      ret.lmx=max(lnode.lmx,lnode.sum+rnode.lmx);
      ret.rmx=max(rnode.rmx,rnode.sum+lnode.rmx);
      ret.mx=max(lnode.rmx+rnode.lmx,max(lnode.mx,rnode.mx));
      return ret;
    }
    
    int n,m;
    
    int main(){
        n=rd();m=rd();
        for(int i=1;i<=n;i++) a[i]=rd();
        build(1,1,n);
        int q,x,y;
        for(int i=1;i<=m;i++){
            q=rd();x=rd();y=rd();
            if(q==1) printf("%d
    ",query(x,y,1,1,n).mx);
            else update(x,1,1,n,y);
        }
        return 0;
    }
    View Code

    T2.fyfy

    上台阶问题升级版,一次上k阶,总数巨大。

    对于一次上k阶,定义f(x)为走到第x阶的方案,显然有f(x)=Σf(i),其中x-k+1<=i<=x-1,且i>=0

    初值f(0)=f(1)=1,注意到k非常小(k<=10),可以开一个矩阵,类比fib数列,就完了。

    复杂度O(logn*k^3)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    int n,m;
    const int MOD=7777777;
    
    
    struct Mat{
        int siz;
        long long a[16][16];
        Mat(int x=10){memset(a,0,sizeof(a));siz=x;}
        Mat operator*(const Mat &rhs){
            Mat ret(m);
            for(int k=0;k<=m;k++){
                for(int i=0;i<=m;i++){
                    for(int j=0;j<=m;j++){
                        (ret.a[i][j]+=(1ll*a[i][k]*rhs.a[k][j])%MOD)%=MOD;
                    }
                }
            }
            return ret;
        }
    }e;
    
    
    Mat qpow(const Mat &x,int y){
        Mat ret=e,base=x;
        while(y){
            if(y&1) ret=ret*base;
            base=base*base;
            y>>=1;
        }
        return ret;
    }
    
    int ans[16];
    
    
    int main(){
        cin>>m>>n;
        e.siz=m;
        Mat cur(m);
        for(int i=0;i<=m;i++) e.a[i][i]=1ll;
        for(int i=0;i<=m-1;i++){
            cur.a[i+1][i]=1ll;
        }
        for(int i=1;i<=m;i++) cur.a[i][m]=1ll;
        Mat ori(m);
        ori.a[0][0]=1ll;ori.a[0][1]=1ll;
        cur=qpow(cur,n+1);
        Mat fn(m);
        fn=ori*cur;
        cout<<fn.a[0][m];
    }
    View Code

    T3.olddriver

    n范围非常小,可以离散化后朴素地标记做。O(n^3)

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=1005;
    
    int orix[MAXN],oriy[MAXN],oriu[MAXN],oriv[MAXN];
    int x[MAXN],y[MAXN],u[MAXN],v[MAXN];
    vector<int> setx,sety;
    int n;
    
    bool mp[MAXN][MAXN];
    
    int main(){
        n=rd();
        for(int i=1;i<=n;i++){
            setx.push_back(orix[i]=rd());
            sety.push_back(oriy[i]=rd());
            setx.push_back(oriu[i]=rd());
            sety.push_back(oriv[i]=rd());
        }
        sort(setx.begin(),setx.end());
        sort(sety.begin(),sety.end());
        for(int i=1;i<=n;i++){
            x[i]=lower_bound(setx.begin(),setx.end(),orix[i])-setx.begin();
            u[i]=lower_bound(setx.begin(),setx.end(),oriu[i])-setx.begin();
            y[i]=lower_bound(sety.begin(),sety.end(),oriy[i])-sety.begin();
            v[i]=lower_bound(sety.begin(),sety.end(),oriv[i])-sety.begin();
        }
        for(int i=1;i<=n;i++)
            for(int j=x[i];j<u[i];j++)
                for(int k=y[i];k<v[i];k++)
                    mp[j][k]=1;
        long long ans=0;
      int    totx=setx.size(),toty=sety.size();
        for(int i=1;i<totx;i++){
            for(int j=1;j<toty;j++){
                if(!mp[i-1][j-1]) continue;
                ans+=(long long)(setx[i]-setx[i-1])*(sety[j]-sety[j-1]);
            }
        }
        cout<<ans;
        return 0;
    }
    View Code

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9342098.html

  • 相关阅读:
    USACO 5.4.2 tour
    USACO 4.4.2 milk6
    USACO 6.1.2 rectbarn
    USACO 4.1.4 cryptcow
    VC++学习笔记之ActiveX
    VC++学习笔记之MFC应用程序创建/执行顺序和MFC运行机制
    FusionCharts Free(一)使用方法和应用实例(asp.net)
    FusionCharts Free(二)使用方法详细解析
    VC++学习笔记之MFC消息映射机制
    MFC基本知识沉淀
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9342098.html
Copyright © 2011-2022 走看看