zoukankan      html  css  js  c++  java
  • 【GMOJ6801】模拟patrick

    题目

    题目链接:https://gmoj.net/senior/#main/show/6801
    给出一个长度为 (n) 的数列,支持单点修改,整体查询超过 (h) 的数字连成的区间个数。

    思路

    建立权值树状数组,第一棵的第 (i) 个位置表示有数列中多少数字等于 (i);第二棵第 (i) 个位置表示数列中有多少位置 (j) 满足 (min(a_j,a_{j+1})=i)
    对于一次询问 (h),答案即为 ((n-bit1.query(h-1))-(n-1-bit2.query(h-1)))
    (=bit1.query(h-1)-bit2.query(h-1)+1)
    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=500010;
    int n,m,last,a[N];
    char type[3];
    
    struct BIT
    {
    	int c[N];
    	
    	void add(int x,int v)
    	{
    		for (int i=x;i<N;i+=i&-i)
    			c[i]+=v;
    	}
    	
    	int query(int x)
    	{
    		int sum=0;
    		for (int i=x;i;i-=i&-i)
    			sum+=c[i];
    		return sum;
    	}
    }bit1,bit2;
    
    int main()
    {
    	freopen("patrick.in","r",stdin);
    	freopen("patrick.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		bit1.add(a[i],1);
    		if (i>1) bit2.add(min(a[i],a[i-1]),1);
    	}
    	while (m--)
    	{
    		scanf("%s",type);
    		if (type[0]=='Q')
    		{
    			int h;
    			scanf("%d",&h); h^=last;
    			last=bit2.query(h-1)-bit1.query(h-1)+1;
    			printf("%d
    ",last);
    		}
    		else
    		{
    			int x,h;
    			scanf("%d%d",&x,&h); x^=last; h^=last;
    			bit1.add(a[x],-1);
    			if (x>1) bit2.add(min(a[x],a[x-1]),-1);
    			if (x<n) bit2.add(min(a[x],a[x+1]),-1);
    			a[x]=h;
    			bit1.add(a[x],1);
    			if (x>1) bit2.add(min(a[x],a[x-1]),1);
    			if (x<n) bit2.add(min(a[x],a[x+1]),1);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    个人笔记 给hover 伪类 恢复默认值
    vue 正则判断
    音乐播放器封装
    jq封装插件,简单dome
    功能齐全轮播
    vue 前端判断输入框不能输入0 空格。特殊符号。
    jq 下拉框
    IPC : 进程间通信方式
    内存
    const char* str 与char str[10]
  • 原文地址:https://www.cnblogs.com/stoorz/p/13827666.html
Copyright © 2011-2022 走看看