zoukankan      html  css  js  c++  java
  • GSS 系列题解

    GSS

    • GSS1

    随便猫树或者线段树,就可以过了
    猫树不说,线段树可以维护左边最大,右边最大,区间最大,区间值然后就做出来了。

    //Isaunoya
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #include<bits/stdc++.h>
    using namespace std ;
    inline int read() { register int x = 0 ; register int f = 1 ; register char c = getchar() ;
    	for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
    	for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
    	return x * f ;
    } int st[105] ;
    template < typename T > inline void write(T x , char c = '
    ') { int tp = 0 ;
    	if(x == 0) return (void) puts("0") ;
    	if(x < 0) putchar('-') , x = -x ;
    	for( ; x ; x /= 10) st[++ tp] = x % 10 ;
    	for( ; tp ; tp --) putchar(st[tp] + '0') ;
    	putchar(c) ;
    }
    //#define Online_Judge
    const int N = 50000 + 10 ;
    int n , m ;
    int a[N] ;
    int p[21][N << 2] , s[21][N << 2] ;
    int Log[N << 2] , d[N << 3] ;
    inline void build(int l , int r , int rt , int dep) {
    	if(l == r) {
    		d[l] = rt ;
    		return ;
    	}
    	int mid = l + r >> 1 ;
    	int sum = 0 , pre = 0 ;
    	p[dep][mid] = s[dep][mid] = sum = pre = a[mid] ;
    	if(sum < 0) sum = 0 ;
    	for(register int i = mid - 1 ; i >= l ; i --) {
    		pre += a[i] ;
    		sum += a[i] ;
    		p[dep][i] = max(p[dep][i + 1] , sum) ;
    		s[dep][i] = max(s[dep][i + 1] , pre) ;
    		if(sum < 0) sum = 0 ;
    	} 
    	p[dep][mid + 1] = s[dep][mid + 1] = sum = pre = a[mid + 1] ;
    	if(sum < 0) sum = 0 ;
    	for(register int i = mid + 2 ; i <= r ; i ++) {
    		pre += a[i] ;
    		sum += a[i] ;
    		p[dep][i] = max(p[dep][i - 1] , sum) ;
    		s[dep][i] = max(s[dep][i - 1] , pre) ;
    		if(sum < 0) sum = 0 ;
    	}
    	build(l , mid , rt << 1 , dep + 1) ;
    	build(mid + 1 , r , rt << 1 | 1 , dep + 1) ;
    }
    inline int Query(int l , int r) {
    	if(l == r) return a[l] ;
    	int st = Log[d[l]] - Log[d[l] ^ d[r]] ;
    	return max(max(p[st][l] , p[st][r]) , s[st][l] + s[st][r]) ;
    }
    
    signed main() {
    #ifdef Online_Judge
    	freopen("testdata.in" , "r" , stdin) ;
    	freopen("testdata2.out" , "w" , stdout) ;
    #endif
    	n = read() ;
    	for(register int i = 1 ; i <= n ; i ++) a[i] = read() ;
    	int len = 2 ;
    	for( ; len < n ; len <<= 1) ;
    	for(register int i = 2 ; i <= len << 1 ; i ++) Log[i] = Log[i >> 1] + 1 ;
    	build(1 , len , 1 , 1) ;
    	m = read() ;
    	for(register int i = 1 ; i <= m ; i ++) {
    		int l = read() , r = read() ;
    		write(Query(l , r)) ;
    	}
    	return 0 ;
    }
    
    • GSS2

    离线,用树状数组的方法加入数字,只不过是要维护历史最值,这题又没了。

    #include <bits/stdc++.h>
    #define rep(i , x , y) for(register int i = (x) , _## i = (y + 1) ; i < _## i ; i ++)
    #define Rep(i , x , y) for(register int i = (x) , _## i = (y - 1) ; i > _## i ; i --)
    using namespace std ;
    using ll = long long ;
    using pii = pair < int , int > ;
    const static int _ = 1 << 20 ;
    char fin[_] , * p1 = fin , * p2 = fin ;
    inline char gc() { return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ; }
    inline int read() {
    	bool sign = 1 ; char c = 0 ; while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
    	int x = (c & 15) ; while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
    	return sign ? x : -x ;
    }
    template < class T > void print(T x , char c = '
    ') {
    	(x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
    	static char _st[100] ; int _stp = 0 ;
    	while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
    	while(_stp) putchar(_st[_stp --]) ; putchar(c) ;
    }
    template < class T > void cmax(T & x , T y) { (x < y) && (x = y) ; }
    template < class T > void cmin(T & x , T y) { (x > y) && (x = y) ; }
    
    int n , q ;
    const int N = 1e5 + 10 ;
    int a[N] ;
    vector < pii > vr[N] ;
    ll ans[N] ;
    int mp[N << 1] ;
    struct Node {
    	ll mx , hsmx , tag , hstag ;
    	Node operator + (const Node & other) const {
    		Node c ;
    		c.mx = max(mx , other.mx) ; c.hsmx = max(hsmx , other.hsmx) ;
    		c.tag = c.hstag = 0 ; return c ;
    	}
    } s[N << 2] ;
    inline void pushdown(int rt) {
      s[rt << 1].hsmx = max(s[rt << 1].hsmx , s[rt << 1].mx + s[rt].hstag) ;
      s[rt << 1].hstag = max(s[rt << 1].hstag , s[rt << 1].tag + s[rt].hstag) ;
      s[rt << 1].mx += s[rt].tag ; s[rt << 1].tag += s[rt].tag ;
      s[rt << 1 | 1].hsmx = max(s[rt << 1 | 1].hsmx , s[rt << 1 | 1].mx + s[rt].hstag) ;
      s[rt << 1 | 1].hstag = max(s[rt << 1 | 1].hstag , s[rt << 1 | 1].tag + s[rt].hstag) ;
      s[rt << 1 | 1].mx += s[rt].tag ; s[rt << 1 | 1].tag += s[rt].tag ;
      s[rt].tag = s[rt].hstag = 0 ;
    }
    void modify(int a , int b , int l , int r , int rt , int val) {
    	if(a <= l && r <= b) {
    		s[rt].mx += val ; s[rt].tag += val ;
    		cmax(s[rt].hsmx , s[rt].mx) ; cmax(s[rt].hstag , s[rt].tag) ;
    		return ;
    	}
    	int mid = l + r >> 1 ; pushdown(rt) ;
    	if(a <= mid) modify(a , b , l , mid , rt << 1 , val) ;
    	if(b > mid) modify(a , b , mid + 1 , r , rt << 1 | 1 , val) ;
    	s[rt] = s[rt << 1] + s[rt << 1 | 1] ;
    }
    Node query(int a , int b , int l , int r , int rt) {
    	if(a <= l && r <= b) return s[rt] ; pushdown(rt) ;
    	int mid = l + r >> 1 ;
    	if(b <= mid) return query(a , b , l , mid , rt << 1) ;
    	if(a > mid) return query(a , b , mid + 1 , r , rt << 1 | 1) ;
    	return query(a , b , l , mid , rt << 1) + query(a , b , mid + 1 , r , rt << 1 | 1) ; 
    }
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	n = read() ;
    	rep(i , 1 , n) a[i] = read() ;
    	q = read() ;
    	rep(i , 1 , q) {
    		int l = read() , r = read() ;
    		vr[r].push_back({ l , i }) ;
    	}
    	rep(i , 1 , n) {
    		modify(mp[a[i] + N] + 1 , i , 1 , n , 1 , a[i]) ;
    		mp[a[i] + N] = i ;
    		for(auto x : vr[i]) ans[x.second] = query(x.first , i , 1 , n , 1).hsmx ;
    	}
    	rep(i , 1 , q) print(ans[i]) ;
    	return 0 ;
    }
    
    • GSS3

    和 GSS1 一个样子,随便写,随便过了…

    // Isaunoya
    #include<bits/stdc++.h>
    using namespace std ;
    #define int long long
    #define fi first
    #define se second
    #define pb push_back
    inline int read() {
      register int x = 0 , f = 1 ;
      register char c = getchar() ;
      for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
      for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
      return x * f ;
    }
    template < typename T > inline bool cmax(T & x , T y) {
      return x < y ? (x = y) , 1 : 0 ;
    }
    template < typename T > inline bool cmin(T & x , T y) {
      return x > y ? (x = y) , 1 : 0 ;
    }
    inline int QP(int x , int y , int Mod){ int ans = 1 ;
      for( ; y ; y >>= 1 , x = (x * x) % Mod)
        if(y & 1) ans = (ans * x) % Mod ;
      return ans ;
    }
    
    int n , q ;
    struct node {
      int l , r , sum , res ;
    } ;
    const int N = 5e4 + 5 ;
    int a[N] ;
    node s[N << 2] ;
    
    inline void pushup(int rt) {
      node l = s[rt << 1] , r = s[rt << 1 | 1] ;
      s[rt].sum = l.sum + r.sum ;
      s[rt].l = max(l.l , l.sum + r.l) ;
      s[rt].r = max(r.r , r.sum + l.r) ;
      s[rt].res = max(l.r + r.l , max(l.res , r.res)) ;
    }
    inline void build(int l , int r , int rt) {
      if(l == r) { s[rt] = {a[l] , a[l] , a[l] , a[l]} ; return ; }
      int mid = l + r >> 1 ;
      build(l , mid , rt << 1)  ;
      build(mid + 1 , r , rt << 1 | 1) ;
      pushup(rt) ;
    }
    inline void modify(int x , int l , int r , int rt , int val) {
      if(l == r) {
        s[rt] = {val , val , val , val} ;
        return ;
      }
      int mid = l + r >> 1 ;
      if(x <= mid) modify(x , l , mid , rt << 1 , val) ;
      else modify(x , mid + 1 , r , rt << 1 | 1 , val) ;
      pushup(rt) ;
    }
    
    inline node Merge(node x , node y) {
      if(x.l == -19260817 && y.l == -19260817) return {-19260817 , -19260817 , -19260817 , -19260817} ;
      if(x.l == -19260817) return y ;
      if(y.l == -19260817) return x ;
      node res ;
      res.sum = x.sum + y.sum ;
      res.l = max(x.l , x.sum + y.l) ;
      res.r = max(y.r , y.sum + x.r) ;
      res.res = max(x.r + y.l , max(x.res , y.res)) ;
      return res ;
    }
    inline node query(int a , int b , int l , int r , int rt) {
      if(a <= l && r <= b) return s[rt] ;
      int mid = l + r >> 1 ;
      node res1 , res2 ;
      res1 = {-19260817 , -19260817 , -19260817 , -19260817} ;
      res2 = {-19260817 , -19260817 , -19260817 , -19260817} ;
      if(a <= mid) res1 = query(a , b , l , mid , rt << 1) ;
      if(b > mid) res2 = query(a , b , mid + 1 , r , rt << 1 | 1) ;
      return Merge(res1 , res2) ;
    }
    signed main() {
      n = read() ;
      for(register int i = 1 ; i <= n ; i ++) a[i] = read() ;
      build(1 , n , 1) ;
      q = read() ;
      while(q --) {
        int opt = read() ;
        if(opt == 1) {
          int x = read() , y = read() ;
          printf("%lld
    " , query(x , y , 1 , n , 1).res) ;
        }
        else {
          int x = read() , y = read() ;
          modify(x , 1 , n , 1 , y) ;
        }
      }
      return 0 ;
    }
    
    • GSS4

    确实水,像是一道分块蓝题…但是线段树也可以做,维护一个区间最值…常用套路?

    然后显然是可以做的,这题没了。

    #include<bits/stdc++.h>
    using namespace std ;
    int n , m ;
    const static int N = 1e5 + 10 ;
    long long a[N] ;
    template < typename T > class SegMentTree {
    	public :
    		T mx[N << 2] , sum[N << 2] ;
    		inline T max(T x , T y) {
    			return x > y ? x : y ;
    		}
    		inline void Push_Up(int rt) {
    			mx[rt] = max(mx[rt << 1] , mx[rt << 1 | 1]) ;
    			sum[rt] = sum[rt << 1] + sum[rt << 1 | 1] ;
    		}
    		inline void build(int l , int r , int rt) {
    			if(l == r) {
    				mx[rt] = sum[rt] = a[l] ;
    				return ;
    			}
    			int mid = l + r >> 1 ;
    			build(l , mid , rt << 1) ;
    			build(mid + 1 , r , rt << 1 | 1) ;
    			Push_Up(rt) ;
    		}
    		inline void Change(int a , int b , int l , int r , int rt) {
    			if(mx[rt] == 1) return ;
    			if(l == r) {
    				mx[rt] = sum[rt] = sqrt(sum[rt]) ;
    				return ;
    			}
    			int mid = l + r >> 1 ;
    			if(a <= mid) Change(a , b , l , mid , rt << 1) ;
    			if(b > mid) Change(a , b , mid + 1 , r , rt << 1 | 1) ;
    			Push_Up(rt) ;
    		}
    		inline T Query(int a , int b , int l , int r , int rt) {
    			if(a <= l && r <= b) return sum[rt] ;
    			int mid = l + r >> 1 ;
    			T ans = 0 ;
    			if(a <= mid) ans += Query(a , b , l , mid , rt << 1) ;
    			if(b > mid) ans += Query(a , b , mid + 1 , r , rt << 1 | 1) ;
    			return ans ;
    		}
    } ;
    SegMentTree < long long > T ;
    signed main() {
    	int cnt = 0 ;
    	while(scanf("%d" , & n) != EOF) {
    		printf("Case #%d:
    ", ++ cnt) ;
    		for(register int i = 1 ; i <= n ; i ++) scanf("%lld" , & a[i]) ;
    		T.build(1 , n , 1) ;
    		scanf("%d" , & m) ;
    		for( ; m -- ; ) {
    			int opt , l , r ;
    			scanf("%d %d %d" , & opt , & l , & r) ;
    			if(l > r) l ^= r ^= l ^= r ;
    			if(opt == 0) T.Change(l , r , 1 , n , 1) ;
    			if(opt == 1) printf("%lld
    " , T.Query(l , r , 1 , n , 1)) ;
    		}
    		puts("") ;
    	}
    	return 0 ;
    }
    
    • GSS5

    猫树,不想说,就是板子
    线段树就分类讨论一下情况,这题没了

    // Isaunoya
    #include<bits/stdc++.h>
    using namespace std ;
    using LL = long long ;
    using uint = unsigned int ;
    #define int long long
    #define fir first
    #define sec second
    #define pb push_back
    #define mp(x , y) make_pair(x , y)
    template < typename T > inline void read(T & x) { x = 0 ; int f = 1 ; register char c = getchar() ;
      for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
      for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
      x *= f ;
    }
    template < typename T > inline void print(T x) {
      if(! x) { putchar('0') ; return ; }
      static int st[105] ;
      if(x < 0) putchar('-') , x = -x ;
      int tp = 0 ;
      while(x) st[++ tp] = x % 10 , x /= 10 ;
      while(tp) putchar(st[tp --] + '0') ;
    }
    template < typename T > inline void print(T x , char c) { print(x) ; putchar(c) ; }
    template < typename T , typename ...Args > inline void read(T & x , Args & ...args) { read(x) ; read(args...) ; }
    template < typename T > inline void sort( vector < T > & v) { sort(v.begin() , v.end()) ; return ; }
    template < typename T > inline void unique( vector < T > & v) { sort(v) ; v.erase(unique(v.begin() , v.end()) , v.end()) ; }
    template < typename T > inline void cmax(T & x , T y) { if(x < y) x = y ; return ; }
    template < typename T > inline void cmin(T & x , T y) { if(x > y) x = y ; return ; }
    const int Mod = LLONG_MAX ;
    inline int QP(int x , int y) { int ans = 1 ;
      for( ; y ; y >>= 1 , x = (x * x) % Mod)
        if(y & 1) ans = (ans * x) % Mod ;
      return ans ;
    }
    template < typename T > inline T gcd(T x , T y) { if(y == 0) return x ; return gcd(y , x % y) ; }
    template < typename T > inline T lcm(T x , T y) { return x * y / gcd(x , y) ; }
    template < typename T > inline void mul(T & x , T y) { x = 1LL * x * y ; if(x >= Mod) x %= Mod ; }
    template < typename T > inline void add(T & x , T y) { if((x += y) >= Mod) x -= Mod ; }
    template < typename T > inline void sub(T & x , T y) { if((x -= y) < 0) x += Mod ; }
    
    int n , q ;
    const int N = 2e5 + 10 ;
    int a[N] , pos[N] , p[16][N] , f[16][N] , sum[16][N] , e_sum[16][N] , lg[N << 2] ;
    
    #define rep(i , j , n) for(register int i = j ; i <= n ; i ++)
    #define Rep(i , j , n) for(register int i = j ; i >= n ; i --)
    inline void build(int l , int r , int k , int d) {
      if(l == r) { pos[l] = k ; return ; }
      int sum1 = 0 , sum2 = 0 , mid = l + r >> 1 ;
      p[d][mid] = f[d][mid] = sum[d][mid] = e_sum[d][mid] = sum1 = sum2 = a[mid] ;
      cmax(sum2 , 0LL) ;
      Rep(i , mid - 1 , l) { sum1 += a[i] , sum2 += a[i] ;
        p[d][i] = max(p[d][i + 1] , sum1) ;
        f[d][i] = max(f[d][i + 1] , sum2) ;
        sum[d][i] = sum1 ;
        e_sum[d][i] = sum2 ;
        cmax(sum2 , 0LL) ;
      }
      p[d][mid + 1] = f[d][mid + 1] = sum[d][mid + 1] = e_sum[d][mid + 1] = sum1 = sum2 = a[mid + 1] ;
      cmax(sum2 , 0LL) ;
      rep(i , mid + 2 , r) { sum1 += a[i] , sum2 += a[i] ;
        p[d][i] = max(p[d][i - 1] , sum1) ;
        f[d][i] = max(f[d][i - 1] , sum2) ;
        sum[d][i] = sum1 ;
        e_sum[d][i] = sum2 ;
        cmax(sum2 , 0LL) ;
      }
      build(l , mid , k << 1 , d + 1) ;
      build(mid + 1 , r , k << 1 | 1 , d + 1) ;
    }
    inline int s_query(int l , int r) {
      if(l > r) return 0 ;
      if(l == r) return a[l] ;
      int d = lg[pos[l]] - lg[pos[l] ^ pos[r]] ;
      return sum[d][l] + sum[d][r] ;
    }
    inline int pre_query(int l , int r) {
      if(l > r) return 0 ;
      if(l == r) return a[l] ;
      int d = lg[pos[l]] - lg[pos[l] ^ pos[r]] ;
      return max(e_sum[d][l] , sum[d][l] + p[d][r]) ;
    }
    inline int suc_query(int l , int r) {
      if(l > r) return 0 ;
      if(l == r) return a[l] ;
      int d = lg[pos[l]] - lg[pos[l] ^ pos[r]] ;
      return max(e_sum[d][r] , sum[d][r] + p[d][l]) ;
    }
    inline int m_query(int l , int r) {
      if(l > r) return 0 ;
      if(l == r) return a[l] ;
      int d = lg[pos[l]] - lg[pos[l] ^ pos[r]] ;
      return max(max(f[d][l] , f[d][r]) , p[d][l] + p[d][r]) ;
    }
    inline int query(int l, int r , int l2 , int r2) {
      int ans = 0 ;
      if(r < l2) return s_query(r + 1 , l2 - 1) + suc_query(l , r) + pre_query(l2 , r2) ;
      ans = m_query(l2 , r) ;
      if(l < l2) cmax(ans , suc_query(l , l2) + pre_query(l2 , r2) - a[l2]) ;
      if(r2 > r) cmax(ans , suc_query(l , r) + pre_query(r , r2) - a[r]) ;
      return ans ;
    }
    signed solve() {
      read(n) ;
      memset(a , 0 , sizeof(a)) ;
      for(register int i = 1 ; i <= n ; i ++) read(a[i]) ;
      read(q) ;
      int len = 2 ; while(len < n) len <<= 1 ;
      build(1 , len , 1 , 1) ;
      while(q -- ) {
        int l , r , l2 , r2 ; read(l , r , l2 , r2) ;
        print(query(l , r , l2 , r2) , '
    ') ;
      }
      return 0 ;
    }
    
    signed main() {
      for(register int i = 2 ; i <= N ; i ++) lg[i] = lg[i >> 1] + 1 ;
      int t ; read(t) ;
      while(t --) {
        solve() ;
      }
    }
    
    • GSS6

    没有NOI2005的那题难,随便写fhq就能过。
    不想写了…代码咕着
    事实证明这玩意改改就能过

    #include<bits/stdc++.h>
    using namespace std ;
    const static int _ = 1 << 20 ;
    char fin[_] , * p1 = fin , * p2 = fin ;
    inline char gc() { return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ; }
    inline int read() {
    	bool sign = 1 ; char c = 0 ; while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
    	int x = (c & 15) ; while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
    	return sign ? x : -x ;
    }
    template < class T > void print(T x , char c = '
    ') {
    	(x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
    	static char _st[100] ; int _stp = 0 ;
    	while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
    	while(_stp) putchar(_st[_stp --]) ; putchar(c) ;
    }
    int n , m , rt , cnt = 0 ;
    constexpr int N = 2e5 + 10 ;
    int a[N] ;
    int rnd[N] , val[N] , sum[N] , sz[N] , ls[N] , rs[N] ;
    int lmax[N] , rmax[N] , mx[N] ;
    int max(int x , int y) {
    	return x > y ? x : y ;
    }
    int min(int x , int y ){
    	return x < y ? x : y ;
    }
    void pushup(int o) {
    	sz[o] = sz[ls[o]] + sz[rs[o]] + 1 ;
    	sum[o] = sum[ls[o]] + sum[rs[o]] + val[o] ;
    	lmax[o] = max(lmax[ls[o]] , sum[ls[o]] + max(0 , lmax[rs[o]]) + val[o]) ;
    	rmax[o] = max(rmax[rs[o]] , sum[rs[o]] + max(0 , rmax[ls[o]]) + val[o]) ;
    	mx[o] = max(0 , rmax[ls[o]]) + max(0 , lmax[rs[o]]) + val[o] ;
    	if(ls[o]) mx[o] = max(mx[o] , mx[ls[o]]) ;
    	if(rs[o]) mx[o] = max(mx[o] , mx[rs[o]]) ;
    }
    int newnode(int k) {
    	++ cnt ;
    	rnd[cnt] = rand() ;
    	val[cnt] = sum[cnt] = k ;
    	lmax[cnt] = rmax[cnt] = mx[cnt] = k ;
    	sz[cnt] = 1 ;
    	ls[cnt] = rs[cnt] = 0 ;
    	return cnt ;
    }
    int merge(int x , int y) {
    	if(! x || ! y) return x | y ;
    	if(rnd[x] < rnd[y]) {
    		rs[x] = merge(rs[x] , y) ;
    		pushup(x) ;
    		return x ;
    	} else {
    		ls[y] = merge(x , ls[y]) ;
    		pushup(y) ;
    		return y ;
    	}
    }
    void split(int cur , int k , int & x , int & y) {
    	if(! cur) {
    		x = y = 0 ;
    		return ;
    	}
    	if(sz[ls[cur]] < k) {
    		split(rs[cur] , k - sz[ls[cur]] - 1 , x , y) ;
    		rs[cur] = 0 ;
    		pushup(cur) ;
    		x = merge(cur , x) ;
    	} else {
    		split(ls[cur] , k , x , y) ;
    		ls[cur] = 0 ;
    		pushup(cur) ;
    		y = merge(y , cur) ;
    	}
    }
    int newrt(int len) {
    	int _newrt = 0 ;
    	for(int i = 1 ; i <= len ; i ++) _newrt = merge(_newrt , newnode(read())) ;
    	return _newrt ;
    }
    void insert(int pos , int len) {
    	int x , y ;
    	split(rt , pos , x , y) ;
    	rt = merge(merge(x , newrt(len)) , y) ;
    }
    void remove(int l , int r) {
    	int x , y , z ;
    	split(rt , l - 1 , x , z) ;
    	split(z , r - l + 1 , y , z) ;
    	rt = merge(x , z) ;
    }
    int query_max_sum(int l , int r) {
    	int x , y , z ;
    	split(rt , l - 1 , x , z) ;
    	split(z , r - l + 1 , y , z) ;
    	int res = mx[y] ;
    	rt = merge(merge(x , y) , z) ;
    	return res ;
    }
    int main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	srand(19260817) ; n = read() ; rt = newrt(n) ; m = read() ;
    	while(m --) {
    		char opt = gc() ;	while(opt < 'D' || opt > 'R') opt = gc() ;
    		if(opt == 'I') {
    			int pos = read() ; pos -- ;
    			insert(pos , 1) ;
    		}
    		if(opt == 'D') {
    			int pos = read() ;
    			remove(pos , pos) ;
    		}
    		if(opt == 'R') {
    			int pos  = read() ;
    			remove(pos , pos) ; pos -- ;
    			insert(pos , 1) ;
    		}
    		if(opt == 'Q') {
    			int l = read() , r = read() ;
    			print(query_max_sum(l , r)) ;
    		}
    	}
    	return 0 ;
    }
    
    • GSS7

    只需要管一下合并,左链翻转/右链翻转,这题就没了。

    虽然说tag初值=0调了好久就是了

    #include <bits/stdc++.h>
    #define rep(i , x , y) for(register int i = (x) , _## i = (y + 1) ; i < _## i ; i ++)
    #define Rep(i , x , y) for(register int i = (x) , _## i = (y - 1) ; i > _## i ; i --)
    using namespace std ;
    using ll = long long ;
    using pii = pair < int , int > ;
    const static int _ = 1 << 20 ;
    char fin[_] , * p1 = fin , * p2 = fin ;
    inline char gc() { return (p1 == p2) && (p2 = (p1 = fin) + fread(fin , 1 , _ , stdin) , p1 == p2) ? EOF : * p1 ++ ; }
    inline int read() {
    	bool sign = 1 ; char c = 0 ; while(c < 48) ((c = gc()) == 45) && (sign = 0) ;
    	int x = (c & 15) ; while((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15) ;
    	return sign ? x : -x ;
    }
    template < class T > void print(T x , char c = '
    ') {
    	(x == 0) && (putchar(48)) , (x < 0) && (putchar(45) , x = -x) ;
    	static char _st[100] ; int _stp = 0 ;
    	while(x) _st[++ _stp] = x % 10 ^ 48 , x /= 10 ;
    	while(_stp) putchar(_st[_stp --]) ; putchar(c) ;
    }
    template < class T > void cmax(T & x , T y) { (x < y) && (x = y) ; }
    template < class T > void cmin(T & x , T y) { (x > y) && (x = y) ; }
    struct Node {
    	int mx , lmx , rmx , sum , tag ;
    	void operator = (int x) { sum = x ; mx = lmx = rmx = max(0 , sum) ; }
    } ;
    Node Merge(Node x , Node y) {
    	Node res ;
    	res.lmx = max(x.lmx , x.sum + y.lmx) ;
    	res.rmx = max(y.rmx , y.sum + x.rmx) ;
    	res.sum = x.sum + y.sum ;
    	res.mx = max(max(x.mx , y.mx) , x.rmx + y.lmx) ;
    	res.tag = 1e7 ;
    	return res ;
    }
    int n , q ;
    const int N = 1e5 + 10 ;
    const int inf = 1e7 ;
    Node s[N << 2] ;
    vector < int > G[N] ;
    int v[N] , a[N] , fa[N] , id[N] , idx = 0 , d[N] , sz[N] , son[N] , top[N] ;
    void dfs(int u) {
    	sz[u] = 1 ; for(auto v : G[u]) {
    		if(v == fa[u]) continue ;
    		fa[v] = u ; d[v] = d[u] + 1 ;
    		dfs(v) ; sz[u] += sz[v] ;
    		if(sz[v] > sz[son[u]]) son[u] = v ;
    	}
    }
    void dfs(int u , int t) {
    	top[u] = t ; a[id[u] = ++ idx] = v[u] ;
    	if(son[u]) dfs(son[u] , t) ;
    	for(auto v : G[u]) {
    		if(v == fa[u] || v == son[u]) continue ;
    		dfs(v , v) ;
    	}
    }
    void build(int l , int r , int rt) {
    	s[rt].tag = inf ;
    	if(l == r) { s[rt] = a[l] ; return ; }
    	int mid = l + r >> 1 ;
    	build(l , mid , rt << 1) ;
    	build(mid + 1 , r , rt << 1 | 1) ;
    	s[rt] = Merge(s[rt << 1] , s[rt << 1 | 1]) ; 
    }
    void cover(int rt , int l , int r , int val) {
    	s[rt] = (r - l + 1) * val ;
    	s[rt].tag = val ;
    }
    void pushdown(int rt , int l , int r) {
    	if(s[rt].tag == inf) return ;
    	int mid = l + r >> 1 ;
    	cover(rt << 1 , l , mid , s[rt].tag) ;
    	cover(rt << 1 | 1 , mid + 1 , r , s[rt].tag) ;
    	s[rt].tag = inf ;
    }
    void change(int a , int b , int l , int r , int rt , int val) {
    	if(a <= l && r <= b) {
    		cover(rt , l , r , val) ;
    		return ;
    	}
    	pushdown(rt , l , r) ;
    	int mid = l + r >> 1 ;
    	if(a <= mid) change(a , b , l , mid , rt << 1 , val) ;
    	if(b > mid) change(a , b , mid + 1 , r , rt << 1 | 1 , val) ;
    	s[rt] = Merge(s[rt << 1] , s[rt << 1 | 1]) ;
    }
    Node query(int a , int b , int l , int r , int rt) {
    	if(a <= l && r <= b) return s[rt] ;
    	pushdown(rt , l , r) ;
    	int mid = l + r >> 1 ;
    	Node L = { 0 , 0 , 0 , 0 , 0 } , R = { 0 , 0 , 0 , 0 , 0 } ;
    	if(a <= mid) L = query(a , b , l , mid , rt << 1) ;
    	if(b > mid) R = query(a , b , mid + 1 , r , rt << 1 | 1) ;
    	return Merge(L , R) ; 
    }
    void change(int x , int y , int val) {
    	while(top[x] != top[y]) {
    		if(d[top[x]] < d[top[y]]) swap(x , y) ;
    		change(id[top[x]] , id[x] , 1 , n , 1 , val) ;
    		x = fa[top[x]] ;
    	}
    	if(d[x] > d[y]) swap(x , y) ;
    	change(id[x] , id[y] , 1 , n , 1 , val) ; 
    }
    Node query(int x , int y) {
    	Node L = { 0 , 0 , 0 , 0 } , R = { 0 , 0 , 0 , 0 } ; 
    	while(top[x] ^ top[y]) {
    		if(d[top[x]] > d[top[y]]) {
    			L = Merge(query(id[top[x]] , id[x] , 1 , n , 1) , L) ;
    			x = fa[top[x]] ;
    		}
    		else {
    			R = Merge(query(id[top[y]] , id[y] , 1 , n , 1) , R) ;
    			y = fa[top[y]] ;
    		}
    	}
    	if(d[x] > d[y]) {
    		L = Merge(query(id[y] , id[x] , 1 , n , 1) , L) ;
    	}
    	else {
    		R = Merge(query(id[x] , id[y] , 1 , n , 1) , R) ;
    	}
    	swap(L.lmx , L.rmx) ;
    	return Merge(L , R) ;
    }
    
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    	freopen("testdata.out" , "w" , stdout) ;
    #endif
    	n = read() ;
    	rep(i , 1 , n) v[i] = read() ;
    	rep(i , 2 , n) {
    		int u = read() , v = read();
    		G[u].push_back(v) ;
    		G[v].push_back(u) ;
    	}
    	dfs(1) ;
    	dfs(1 , 1) ;
    	build(1 , n , 1) ;
    	q = read() ;
    	while(q --) {
    		int opt = read() ;
    		if(opt == 1) {
    			int x = read() , y = read() ;
    			print(query(x , y).mx) ;
    		}
    		else {
    			int x = read() , y = read() , val = read() ;
    			change(x , y , val) ;
    		}
    	}
    	return 0 ;
    }
    
    • GSS8

    还没写,咕着。

  • 相关阅读:
    Vue 2.x windows环境下安装
    VSCODE官网下载缓慢或下载失败 解决办法
    angular cli 降级
    Win10 VS2019 设置 以管理员身份运行
    XSHELL 连接 阿里云ECS实例
    Chrome浏览器跨域设置
    DBeaver 执行 mysql 多条语句报错
    DBeaver 连接MySql 8.0 报错 Public Key Retrieval is not allowed
    DBeaver 连接MySql 8.0报错 Unable to load authentication plugin 'caching_sha2_password'
    Linux系统分区
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12070639.html
Copyright © 2011-2022 走看看