zoukankan      html  css  js  c++  java
  • 2020 CCPC-Wannafly Winter Camp Day3 ---H. 火山哥的序列

    2020 CCPC-Wannafly Winter Camp Day3 ---H. 火山哥的序列

    题意:

    解法:

    显然是要枚举每个gcd来计算贡献的。我们考虑从大向小枚举gcd,这样可以避免重复计算。我们将gcd设为g。对于每个g,我们可以得到序列中它的倍数a[1],a[2]...,a[k-1],a[k]。
    考虑删除区间,至少留下的情况可能是a[1]和a[2],a[1]和a[k],a[k-1]和a[k]。即对于1~a[1]位置的为左端点,右端点最多可以删到a[k-1]-1,对于a[1]+1-a[2]的数为左端点,最多可以山道a[k]-1,对于a[2]+1-n位置为左端点,可以删到n。这样我们可以维护每个位置最多删到哪,每次更新,多出来的区间就是以g为gcd的贡献。

    #include <bits/stdc++.h>
    #define ll long long
    #define lson rt << 1
    #define rson rt << 1 | 1
    using namespace std;
    const int maxn = 2e5;
    int n,m;
    
    struct node {
    	ll sum;
    	int fm,sm,cnt;
    }tree[4 * maxn + 11];
    
    int pos[maxn + 11];
    
    void push_up(int rt) {
    	tree[rt].sum = tree[lson].sum + tree[rson].sum;
    	if (tree[lson].fm < tree[rson].fm) {
    		tree[rt].fm = tree[lson].fm; tree[rt].cnt = tree[lson].cnt;
    		tree[rt].sm = min(tree[lson].sm , tree[rson].fm);
    	}
    	else if (tree[lson].fm > tree[rson].fm) { 
    		tree[rt].fm = tree[rson].fm; tree[rt].cnt = tree[rson].cnt;
    		tree[rt].sm = min(tree[rson].sm , tree[lson].fm);
    	} 
    	else {
    		tree[rt].fm = tree[rson].fm; tree[rt].cnt = tree[rson].cnt + tree[lson].cnt;
    		tree[rt].sm = min(tree[rson].sm , tree[lson].sm);
    	}
    } 
    
    void upd(int rt,int val) {
    	if (tree[rt].fm >= val) return;
    	tree[rt].sum += 1ll * (val - tree[rt].fm) * tree[rt].cnt;
    	tree[rt].fm = val;
    }
    
    void push_down(int rt) {
    	upd(lson , tree[rt].fm);
    	upd(rson , tree[rt].fm);
    } 
    
    void build(int rt,int l,int r) {
    	if (l == r) {
    		tree[rt].sum = 0;
    		tree[rt].fm = l - 1; tree[rt].sm = n + 1; tree[rt].cnt = 1;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(lson , l , mid);
    	build(rson , mid + 1 , r);
    	push_up(rt);
    }
    
    void update(int rt,int l,int r,int al,int ar,int val) {
    	if (l > ar || r < al || tree[rt].fm >= val) return;
    	if (l >= al && r <= ar && tree[rt].sm >= val) { upd(rt , val); return; }
    	int mid = (l + r) >> 1;
    	push_down(rt);
    	update(lson , l , mid , al , ar , val);
    	update(rson , mid + 1 , r , al , ar , val);
    	push_up(rt);
    } 
    
    int main(){
    	int t;
    	scanf("%d" , &t);
    	while (t--) {
    		scanf("%d" , &n);
    		m = 0;
    		for (int i = 1; i <= maxn; i++) pos[i] = 0;
    		for (int i = 1; i <= n; i++) {
    			int x;
    			scanf("%d" , &x);
    			pos[x] = i; m = max(m , x);
    		}
    		build(1 , 1, n);
    		ll ans = 0;
    		for (int g = m; g >= 1; g--) {
    			int a = n + 1; int b = n + 1;
    			int c = 0; int d = 0;
    			for (int i = g; i <= m; i += g){
    				if (!pos[i]) continue;
    				if (pos[i] <= a) { b = a; a = pos[i]; }
    				else if (pos[i] < b) b = pos[i];
    				if (pos[i] >= d) { c = d; d = pos[i]; }
    				else if (pos[i] > c) c = pos[i];
    			}
    			if (b == n + 1) continue;
    			ll num = tree[1].sum;
    			if (c == a) {
    				if (a > 1) update(1 , 1 , n , 1 , a - 1 , a - 1);
    				if (a + 1 <= b - 1) update(1 , 1 , n , a + 1 , b - 1 , b - 1);
    				if (b < n) update(1 , 1 , n , b + 1 , n , n);
    			}
    			else if (c == b) {
    				c = d;
    				update(1 , 1 , n , 1 , a , b - 1);
    				if (a + 1 <= b - 1) update(1 , 1 , n , a + 1 , b , c - 1);
    				update(1 , 1 , n , b + 1 , n , n);
    			}
    			else {
    				update(1 , 1 , n , 1 , a , c - 1);
    				update(1 , 1 , n , a + 1 , b , d - 1);
    				update(1 , 1 , n , b + 1 , n , n);
    			} 
    			num = tree[1].sum - num;
    			ans += num * g;
    		} 
    		printf("%lld
    " , ans);
    	} 
    } 
    
  • 相关阅读:
    #Leetcode# 21. Merge Two Sorted Lists
    #Leetcode# 118. Pascal's Triangle
    #LeetCode# 136. Single Number
    #Leetcode# 26. Remove Duplicates from Sorted Array
    #LeetCode# 167. Two Sum II
    #Leetcode# 58. Length of Last Word
    #LeetCode# 35. Search Insert Position
    POJ 2492 J-A Bug's Life
    #Leetcode# 27. Remove Element
    【前端】.easyUI.c#
  • 原文地址:https://www.cnblogs.com/Embiid/p/12299926.html
Copyright © 2011-2022 走看看