bzoj1901[Zju2112] Dynamic Rankings / hdu5412 CRB and Queries 整体二分基础摸板

题目链接:bzoj1901 hdu5412

题目大意:带修改的区间第K小


题解:

整体二分

啊看了某个大神说,这是奇技淫巧orzorzorz
因为多了修改,而修改前已经对树状数组产生了影响,所以在面对一个修改操作的时候要先把之前的影响去掉。
how?(奇技淫巧来了。。。 

对于同一个点上的修改,在修改操作之前增加一个操作,标记为tag=3,就表示把之前的值的贡献减掉。[tag=1表示修改,tag=2表示询问

因为操作序列是按时间维度来排的序,而且在分治时的顺序是严格不变的。所以在执行修改操作之前因为加了上面那个操作就已经处理完了,嗯所以一点问题都没有[我纠结了这个纠结了好久qwq。

坑爹的hdu是多组数据qwq好吧是我瞎,还以为跟bzoj上的差不多。对拍了一个早上!!!


简直了!


bzoj1901:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 50100
#define inf 0x7fffffff

struct node
{
	int x,y,c,tg,ans;
}q[maxn];int n,m,num;
int id[maxn],cur[maxn],tmp[maxn];
int tol[maxn],tor[maxn],c[maxn],a[maxn];
int lowbit(int x){return x&(-x);}
void change(int x,int k)
{
	for (x;x<=n;x+=lowbit(x)) c[x]+=k;
}
int query(int x)
{
	int ret=0;
	for (x;x>0;x-=lowbit(x)) ret+=c[x];
	return ret;
}
void solve(int head,int tail,int l,int r)
{
	if (head>tail) return;
	int i,lnum=0,rnum=0;
	int mid=(l+r)>>1;
	if (l==r)
	{
		for (i=head;i<=tail;i++) if (q[id[i]].tg==2)
			q[id[i]].ans=l;
		return;
	}
	for (i=head;i<=tail;i++)
	 if (q[id[i]].tg==1)
	 {
		 if (q[id[i]].x<=mid) tol[++lnum]=id[i],change(q[id[i]].y,1);
		 else tor[++rnum]=id[i];
	 }
	 else if (q[id[i]].tg==3)
	 {
		 if (q[id[i]].x<=mid) tol[++lnum]=id[i],change(q[id[i]].y,-1);
		 else tor[++rnum]=id[i];
	 }
	 else 
	 {
		 tmp[id[i]]=query(q[id[i]].y)-query(q[id[i]].x-1);
		 if (tmp[id[i]]+cur[id[i]]>=q[id[i]].c) tol[++lnum]=id[i];
		 else cur[id[i]]+=tmp[id[i]],tor[++rnum]=id[i];
	 }
	for (i=head;i<=tail;i++)
	 if (q[id[i]].tg==1 && q[id[i]].x<=mid) change(q[id[i]].y,-1);
	 else if (q[id[i]].tg==3 && q[id[i]].x<=mid) change(q[id[i]].y,1);
	for (i=0;i<lnum;i++) id[head+i]=tol[i+1];
	for (i=0;i<rnum;i++) id[head+i+lnum]=tor[i+1];
	solve(head,head+lnum-1,l,mid);
	solve(head+lnum,tail,mid+1,r);
}
int main()
{
	char cc;int i;num=0;
	scanf("%d%d",&n,&m);
	memset(c,0,sizeof(c));
	for (i=1;i<=n;i++)
	{
		id[++num]=num;
		scanf("%d",&q[num].x);
		q[num].y=i;q[num].tg=1;
		a[i]=q[num].x;
	}
	for (i=1;i<=m;i++)
	{
		scanf("\n%c",&cc);
		if (cc=='C')
		{
			id[++num]=num;q[num].tg=3;id[++num]=num;
			scanf("%d%d",&q[num].y,&q[num].x);
			q[num-1].y=q[num].y;q[num-1].x=a[q[num].y];
			q[num].tg=1;a[q[num].y]=q[num].x;
		}else
		{
			id[++num]=num;
			scanf("%d%d%d",&q[num].x,&q[num].y,&q[num].c);
			q[num].tg=2;q[num].ans=0;
		}
	}
	solve(1,num,0,inf);
	for (i=1;i<=num;i++) if (q[i].tg==2) printf("%d\n",q[i].ans);
	return 0;
}


hdu5412:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 310000
#define inf 1e9
typedef long long LL;

struct node
{
	LL l,r,c,tg;LL ans;
}q[maxn];LL n,m,c[maxn],id[maxn];
LL cur[maxn],tol[maxn],tor[maxn],a[maxn];
LL lowbit(LL x){return x&(-x);}
void change(LL x,LL k)
{
	for (x;x<=n;x+=lowbit(x)) c[x]+=k;
}
LL query(LL x)
{
	LL ret=0;
	for (x;x>0;x-=lowbit(x)) ret+=c[x];
	return ret;
}
void solve(LL head,LL tail,LL l,LL r)
{
	if (head>tail) return;
	LL lnum=0,rnum=0,i;LL mid=(l+r)>>1;
	if (l==r)
	{
		for (i=head;i<=tail;i++) if (q[id[i]].tg==2) q[id[i]].ans=l;
		return;
	}
	for (i=head;i<=tail;i++)
	  if (q[id[i]].tg==1)
	  {
		  if (q[id[i]].r<=mid) change(q[id[i]].l,1),tol[++lnum]=id[i];
		  else tor[++rnum]=id[i];
	  }
	  else if (q[id[i]].tg==3)
	  {
		  if (q[id[i]].r<=mid) change(q[id[i]].l,-1),tol[++lnum]=id[i];
		  else tor[++rnum]=id[i];
	  }
	  else
	  {
		  LL now=query(q[id[i]].r)-query(q[id[i]].l-1);
		  if (now+cur[id[i]]>=q[id[i]].c) tol[++lnum]=id[i];
		  else cur[id[i]]+=now,tor[++rnum]=id[i];
	  }
	for (i=head;i<=tail;i++)
	  if (q[id[i]].tg==1 && q[id[i]].r<=mid) change(q[id[i]].l,-1);
	  else if (q[id[i]].tg==3 && q[id[i]].r<=mid) change(q[id[i]].l,1);
	for (i=0;i<lnum;i++) id[head+i]=tol[i+1];
	for (i=0;i<rnum;i++) id[head+i+lnum]=tor[i+1];
	solve(head,head+lnum-1,l,mid);
	solve(head+lnum,tail,mid+1,r);
}
int main()
{
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	LL x,i,cc,l,r,t;
	while (scanf("%lld",&n)!=EOF)
	{
		memset(c,0,sizeof(c));t=0;
		memset(cur,0,sizeof(cur));
		for (i=1;i<=n;i++)
		{
			scanf("%lld",&x);
			id[++t]=t;a[i]=x;
			q[t].l=i;q[t].r=x;q[t].tg=1;
		}
		scanf("%lld",&m);
		for (i=1;i<=m;i++)
		{
			scanf("%lld%lld%lld",&cc,&l,&r);
			if (cc==1)
			{
				id[++t]=t;q[t].l=l;q[t].r=a[l];q[t].tg=3;
				id[++t]=t;q[t].l=l;q[t].r=r;q[t].tg=1;a[l]=r;
			}else
			{
				scanf("%lld",&x);id[++t]=t;
				q[t].c=x;q[t].l=l;q[t].r=r;q[t].tg=2;
			}
		}
		solve(1,t,1,inf);
		for (i=1;i<=t;i++) if (q[i].tg==2) printf("%lld\n",q[i].ans);
	}
	return 0;
}


转载于:https://www.cnblogs.com/Euryale-Rose/p/6527817.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值