zoukankan      html  css  js  c++  java
  • 【BZOJ2138】stone

    题面

    http://darkbzoj.tk/problem/2138

    题解

    用类前缀和维护在给定的区间内的所有区间的价值之和,再用线段树维护区间最值。

    把求全局最值转换成求当前区间左右最值那一步非常妙,是为了求出这块区域最多能被拿走多少块石子。

    #include<stack>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define N 45000
    #define ri register int
    using namespace std;
    
    int a[N],k[N],sum[N];
    int n,m;
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    int sqr(int x) {
      return x*x;
    }
    
    struct segment_tree {
      int t1[N<<2],t2[N<<2];
      int tag1[N<<2],tag2[N<<2];
      void maketree(int x,int l,int r) {
        if (l==r) {
          t1[x]=t2[x]=sum[l];
          return;
        }
        int mid=(l+r)/2;
        maketree(x<<1,l,mid); maketree(x<<1|1,mid+1,r);
        t1[x]=max(t1[x<<1],t1[x<<1|1]);
        t2[x]=min(t2[x<<1],t2[x<<1|1]);
      }
      void pushdown1(int x) {
        int k=tag1[x]; tag1[x]=0;
        t1[x<<1]+=k;   tag1[x<<1]+=k;
        t1[x<<1|1]+=k; tag1[x<<1|1]+=k;
      }
      void pushdown2(int x) {
        int k=tag2[x]; tag2[x]=0;
        t2[x<<1]+=k;   tag2[x<<1]+=k;
        t2[x<<1|1]+=k; tag2[x<<1|1]+=k;
      }
      void modify1(int x,int lb,int rb,int l,int r,int k) {
        if (l<=lb && rb<=r) {
          t1[x]+=k; tag1[x]+=k;
          return;
        }
        if (l>rb || r<lb) return;
        pushdown1(x);
        int mid=(lb+rb)/2;
        modify1(x<<1,lb,mid,l,r,k); modify1(x<<1|1,mid+1,rb,l,r,k);
        t1[x]=max(t1[x<<1],t1[x<<1|1]);
      }
      void modify2(int x,int lb,int rb,int l,int r,int k) {
        if (l<=lb && rb<=r) {
          t2[x]+=k; tag2[x]+=k;
          return;
        }
        if (l>rb || r<lb) return;
        pushdown2(x);
        int mid=(lb+rb)/2;
        modify2(x<<1,lb,mid,l,r,k); modify2(x<<1|1,mid+1,rb,l,r,k);
        t2[x]=min(t2[x<<1],t2[x<<1|1]);
      }
      int query1(int x,int lb,int rb,int l,int r) {
        if (l<=lb && rb<=r) return t1[x];
        if (l>rb || r<lb) return -1e9;
        pushdown1(x);
        int mid=(lb+rb)/2;
        return max(query1(x<<1,lb,mid,l,r),query1(x<<1|1,mid+1,rb,l,r));
      }
      int query2(int x,int lb,int rb,int l,int r) {
        if (l<=lb && rb<=r) return t2[x];
        if (l>rb || r<lb) return 1e9;
        pushdown2(x);
        int mid=(lb+rb)/2;
        return min(query2(x<<1,lb,mid,l,r),query2(x<<1|1,mid+1,rb,l,r));
      }
    } T;
    
    int main() {
      n=read();
      int x=read(),y=read(),z=read(),p=read();
      for (ri i=1;i<=n;i++) a[i]=(sqr(i-x)+sqr(i-y)+sqr(i-z))%p;
      m=read();
      k[1]=read(); k[2]=read(); x=read(),y=read(),z=read(),p=read();
      for (ri i=3;i<=m;i++) k[i]=(x*k[i-1]+y*k[i-2]+z)%p;
      for (ri i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
      T.maketree(1,1,n);
      for (ri i=1;i<=m;i++) {
        int l=read(),r=read();
        k[i]=min(k[i],T.query2(1,1,n,r,n)-max(T.query1(1,1,n,1,l-1),0));
        printf("%d
    ",k[i]);
        T.modify1(1,1,n,l,n,-k[i]); T.modify2(1,1,n,r,n,-k[i]);
      }
      return 0;
    }
  • 相关阅读:
    LeetCode OJ 112. Path Sum
    LeetCode OJ 226. Invert Binary Tree
    LeetCode OJ 100. Same Tree
    LeetCode OJ 104. Maximum Depth of Binary Tree
    LeetCode OJ 111. Minimum Depth of Binary Tree
    LeetCode OJ 110. Balanced Binary Tree
    apache-jmeter-3.1的简单压力测试使用方法(下载和安装)
    JMeter入门教程
    CentOS6(CentOS7)设置静态IP 并且 能够上网
    分享好文:分享我在阿里8年,是如何一步一步走向架构师的
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11323893.html
Copyright © 2011-2022 走看看