zoukankan      html  css  js  c++  java
  • JZOJ 6801. NOIP2020.9.19模拟patrick

    题目大意

    动态维护数列中大于等于某个数的极长连续段的个数。

    思路

    我们考虑每段的开头,记为 (i),高度为 (a_i)
    那么此时水淹的高度必然满足 (a_{i-1} < x leq a_i)
    这样的 (x) 在此处会给答案贡献加一
    那么我们考虑所有的这种位置,开一棵权值线段树,对于这些 (x) 的位置都加 (1)
    询问时就单点查询 (x) 在线段树种的值就行了
    修改时注意它原来的贡献,包括它与前面的数和它与后面的数
    这些减去,修改后在加上新的贡献
    然后,就没有然后了······

    (Code)

    #include<cstdio>
    #define ls (k << 1)
    #define rs (ls | 1)
    using namespace std;
    
    const int N = 5e5;
    int n , m , a[N + 5] , last;
    struct seg{
    	int sum , tag;
    }t[4 * N + 5];
    
    void pushdown(int k , int l , int r)
    {
    	if (!t[k].tag) return;
    	int m = (l + r) >> 1;
    	t[ls].sum += (m - l + 1) * t[k].tag , t[ls].tag += t[k].tag;
    	t[rs].sum += (r - m) * t[k].tag , t[rs].tag += t[k].tag;
    	t[k].tag = 0;
    }
    
    void pushup(int k){t[k].sum = t[ls].sum + t[rs].sum;}
    
    void update(int l , int r , int k , int x , int y , int v)
    {
    	if (x <= l && r <= y)
    	{
    		t[k].sum += (r - l + 1) * v;
    		t[k].tag += v;
    		return;
    	}
    	pushdown(k , l , r);
    	int mid = (l + r) >> 1;
    	if (x <= mid) update(l , mid , ls , x , y , v);
    	if (y > mid) update(mid + 1 , r , rs , x , y , v);
    	pushup(k);
    }
    
    int query(int l , int r , int k , int x)
    {
    	if (l == r && l == x) return t[k].sum;
    	pushdown(k , l , r);
    	int mid = (l + r) >> 1;
    	if (x <= mid) return query(l , mid , ls , x);
    	else return query(mid + 1 , r , rs , x);
    }
    
    int main()
    {
    	freopen("patrick.in" , "r" , stdin);
    	freopen("patrick.out" , "w" , stdout);
    	scanf("%d%d" , &n , &m);
    	for(register int i = 1; i <= n; i++)
    	{
    		scanf("%d" , a + i);
    		if (a[i] > N) a[i] = N;
    		if (a[i] > a[i - 1]) update(1 , N , 1 , a[i - 1] + 1 , a[i] , 1);
    	}
    	char opt[5]; int x , y;
    	for(register int i = 1; i <= m; i++)
    	{
    		scanf("%s" , opt);
    		if (opt[0] == 'Q')
    		{
    			scanf("%d" , &x) , x ^= last;
    			last = query(1 , N , 1 , x);
    			printf("%d
    " , last);
    		}
    		else {
    			scanf("%d%d" , &x , &y) , x ^= last , y ^= last;
    			if (a[x] > a[x - 1]) update(1 , N , 1 , a[x - 1] + 1 , a[x] , -1);
    			if (a[x + 1] > a[x]) update(1 , N , 1 , a[x] + 1 , a[x + 1] , -1);
    			a[x] = y;
    			if (a[x] > a[x - 1]) update(1 , N , 1 , a[x - 1] + 1 , a[x] , 1);
    			if (a[x + 1] > a[x]) update(1 , N , 1 , a[x] + 1 , a[x + 1] , 1);
    		}
    	}
    }
    
  • 相关阅读:
    单例模式(singleton)
    Unsupported major.minor version 51.0
    “万能数据库查询分析器”4.03发布,谨以此致我们终将逝去的青春
    和菜鸟一起学linux内核之初始化init篇
    PL/SQL备份oracle数据库
    java.lang.ClassCastException: org.apache.struts.taglib.bean.CookieTei
    DB Query Analyzer 4.03 is upgraded in ZOL
    Android应用程序资源的查找过程分析
    java.lang.IllegalArgumentException: Can't convert argument: null
    Dalvik虚拟机简要介绍和学习计划
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/13696226.html
Copyright © 2011-2022 走看看