首页 > 其他分享 >ICPC2020 南京J 吉司机线段树

ICPC2020 南京J 吉司机线段树

时间:2022-12-13 10:34:12浏览次数:51  
标签:yy ICPC2020 int 线段 司机 zz ask include define

题目是一个序列。
两个操作 1 对L,R里的所有数字对输入x取max。
2 询问L,R里某一位二进制位的1的个数。
n是正常的200000

用线段树来维护两个操作。先考虑第一个操作用吉司机树的做法维护一个最小值m 最小值次数mn 次小值s。

这样当x来到某个区间若m>=x就直接跳过了若mn>=x就可以直接把最小值修改掉打上标记。反之暴力向下递归。

容易想到这样做复杂度是有保证的。

对于操作2维护区间每一位1的个数即可,对于操作1的修改这个数组也很容易维护出来。

END.

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1100000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(w) t[w].l
#define r(w) t[w].r
#define m(w) t[w].m
#define mn(w) t[w].mn
#define c(w) t[w].c
#define s(w) t[w].s
#define tag(w) t[w].tag
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define zz p<<1
#define yy p<<1|1
using namespace std;
const int MAXN=200010,maxn=1000010;
int n,q;
int a[MAXN];
struct wy
{
	int l,r;
	int m,c,mn;
	int s,tag;
	int b[32];
}t[MAXN<<2];
inline void pushup(int p)
{
	if(m(zz)==m(yy))
	{
		m(p)=m(zz);
		c(p)=c(zz)+c(yy);
		mn(p)=min(mn(zz),mn(yy));
	}
	else
	{
		if(m(zz)<m(yy))
		{
			m(p)=m(zz);
			c(p)=c(zz);
			mn(p)=min(mn(zz),m(yy));
		}
		else
		{
			m(p)=m(yy);
			c(p)=c(yy);
			mn(p)=min(mn(yy),m(zz));
		}
	}
	s(p)=s(zz)^s(yy);
	rep(0,29,i)t[p].b[i]=(t[zz].b[i]+t[yy].b[i]);
}
inline void build(int p,int l,int r)
{
	l(p)=l;r(p)=r;
	tag(p)=-1;
	if(l==r)
	{
		m(p)=a[l];
		mn(p)=INF;
		c(p)=1;
		s(p)=a[l];
		rep(0,29,i)t[p].b[i]=(a[l]>>i)&1;
		return;
	}
	int mid=(l+r)>>1;
	build(zz,l,mid);
	build(yy,mid+1,r);
	pushup(p);
}
inline void pushdown(int p)
{
	int x=tag(p);tag(p)=-1;
	if(m(zz)>=x);
	else
	{
		rep(0,29,i)t[zz].b[i]+=(((x>>i)&1)-((m(zz)>>i)&1))*c(zz);
		if(c(zz)&1)s(zz)=s(zz)^m(zz)^x;
		m(zz)=x;tag(zz)=x;
	}
	if(m(yy)>=x);
	else
	{
		rep(0,29,i)t[yy].b[i]+=(((x>>i)&1)-((m(yy)>>i)&1))*c(yy);
		if(c(yy)&1)s(yy)=s(yy)^m(yy)^x;
		m(yy)=x;tag(yy)=x;
	}
}
inline void modify(int p,int l,int r,int x)
{
	if(l<=l(p)&&r>=r(p))
	{
		if(m(p)>=x)return;//最小值大于x
		if(mn(p)>=x)//次小值大于x
		{
			rep(0,29,i)t[p].b[i]+=(((x>>i)&1)-((m(p)>>i)&1))*c(p);
			if(c(p)&1)s(p)=s(p)^m(p)^x;
			m(p)=x;
			tag(p)=x;
			return;
		}
	}
	int mid=(l(p)+r(p))>>1;
	if(tag(p)!=-1)pushdown(p);
	if(l<=mid)modify(zz,l,r,x);
	if(r>mid)modify(yy,l,r,x);
	pushup(p);
}
inline int ask(int p,int l,int r)
{
	if(l<=l(p)&&r>=r(p))return s(p);
	int mid=(l(p)+r(p))>>1;
	if(tag(p)!=-1)pushdown(p);
	if(r<=mid)return ask(zz,l,r);
	if(l>mid)return ask(yy,l,r);
	return ask(zz,l,r)^ask(yy,l,r);
}
inline int ask(int p,int l,int r,int x)
{
	if(l<=l(p)&&r>=r(p))return t[p].b[x];
	int mid=(l(p)+r(p))>>1;
	if(tag(p)!=-1)pushdown(p);
	if(r<=mid)return ask(zz,l,r,x);
	if(l>mid)return ask(yy,l,r,x);
	return ask(zz,l,r,x)+ask(yy,l,r,x);
}
int main()
{
//	freopen("1.in","r",stdin);
	sc(n);sc(q);
	rep(1,n,i)sc(a[i]);
	build(1,1,n);
	rep(1,q,i)
	{
		int op,l,r,x;
		sc(op);sc(l);sc(r);sc(x);
		if(op==1)modify(1,l,r,x);
		else
		{
			int ww=ask(1,l,r)^x;
			if(!ww){put(0);continue;}
			int cc;
			rep(0,29,j)if((ww>>j)&1)cc=j;
			//put(cc);
			put(ask(1,l,r,cc)+((x>>cc)&1));
		}
	}
	//rep(1,n,i)put_(ask(1,i,i));
	return 0;
}

标签:yy,ICPC2020,int,线段,司机,zz,ask,include,define
From: https://www.cnblogs.com/chdy/p/16977860.html

相关文章

  • AcWing 261. 旅馆 【线段树】
    [NOIP2015普及组]推销员题目背景NOIP2015普及组T4题目描述阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧......
  • codeforces 1354D - Multiset (线段树或者2分)
    题目大意:已知一个数列an,我们每次可以添加一个数k,或者把第k大的数字去掉。问我们经过k次操作后,数列中任意1个剩余的数字。n,q<=1e6解题思路:首先最简单的思路是线段树。线段......
  • 线段树专题
    线段树专题线段树与树状数组的视频教程,非常清晰,强烈推荐一、线段树基础1.线段树简介线段树是算法竞赛中常用的用来维护区间信息的数据结构。线段树可以在很小的时间......
  • 线段简化的几种算法
    翻译自:https://www.codeproject.com/Articles/114797/Polyline-Simplification#headingDPN参考:https://www.codeproject.com/Articles/114797/Polyline-Simplification......
  • 线段树优化
    有些修改是无效的修改,对于部分的修改,我们修改是无用的.例子维护一颗线段树,支持单点修改,区间和,区间取模操作.思路显然,如果对于一个修改区间,如果最大值小于这个模数,......
  • 老司机带带你,教你学会Java中又骚又暴力的“反射”技术
    在Java中有这么一个很骚的技术,几乎贯穿了所有主流的框架,在所有主流框架的底层中你都可以看见它的身影,这个技术就是反射。关于反射,有很多小白会觉得很难,搞不清楚到底是怎么回......
  • 李超线段树
    初学笔记,目前水平仅限于板子。李超线段树可以维护很多直线(或者线段),并可以查询某个点上最高点或者最低点。思想是考虑当前线段可能会更新哪些区间,对于一个区间而言,有一个之......
  • 可持久化Trie and 线段树常见扩展
    可持久化数据结构可持久化Trie思想概述可持久化数据结构,是一种对原本数据结构进行的扩展,可以支持查询以前的历史版本的信息在进行每一次操作的时候,我们都把需要更新的......
  • P3834 【模板】可持久化线段树 2
    【模板】可持久化线段树2题目背景这是个非常经典的可持久化权值线段树入门题——静态区间第\(k\)小。数据已经过加强,请使用可持久化权值线段树。同时请注意常数优化......
  • 【小航的算法日记】线段树
    本内容取经于:https://leetcode.cn/problems/my-calendar-i/solution/by-lfool-xvpv/一、概念概念区分:线段树解决的是「区间和」的问题,且该「区间」会被修改前缀和解决的是......