zoukankan      html  css  js  c++  java
  • #权值线段树#洛谷 3939 数颜色

    题目


    分析

    考虑按照颜色建权值线段树,交换直接删除再添加就可以了
    如果离散化要特判不过其实不需要离散化


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=300011;
    int n,Q,w[N<<5],ls[N<<5],cnt,rs[N<<5],rt[N],a[N];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void update(int &k,int l,int r,int x,int y){
    	if (!k) k=++cnt; w[k]+=y;
    	if (l==r) return;
    	rr int mid=(l+r)>>1;
    	if (x<=mid) update(ls[k],l,mid,x,y);
    	    else update(rs[k],mid+1,r,x,y);
    }
    inline signed query(int k,int l,int r,int x,int y){
    	if (!k) return 0;
    	if (l==x&&r==y) return w[k];
    	rr int mid=(l+r)>>1;
    	if (y<=mid) return query(ls[k],l,mid,x,y);
    	else if (x>mid) return query(rs[k],mid+1,r,x,y);
    	else return query(ls[k],l,mid,x,mid)+query(rs[k],mid+1,r,mid+1,y);
    }
    signed main(){
    	n=iut(); Q=iut();
    	for (rr int i=1;i<=n;++i) update(rt[a[i]=iut()],1,n,i,1);
    	while (Q--){
    		rr int o=iut();
    		if (o==1){
    			rr int l=iut(),r=iut(),z=iut();
    			print(query(rt[z],1,n,l,r)),putchar(10);
    		}else{
    			rr int x=iut();
    			if (a[x]==a[x+1]) continue;
    			update(rt[a[x]],1,n,x,-1);
    			update(rt[a[x+1]],1,n,x+1,-1);
    			update(rt[a[x]],1,n,x+1,1);
    			update(rt[a[x+1]],1,n,x,1);
    			a[x]^=a[x+1],a[x+1]^=a[x],a[x]^=a[x+1]; 
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java初学—类与对象
    linux dd命令测试U盘读写速度
    路由器的几种访问方式
    制作Linux启动盘并安装Linux系统到实体机
    RAID阵列与LVM逻辑卷组创建
    有关Linux下库的概念、生成和升级和使用等
    LInux中VIM的使用和定制
    如何通过mount命令挂载存储设备
    硬盘分区和系统启动
    RAID阵列与LVM逻辑卷组原理
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13695622.html
Copyright © 2011-2022 走看看