整体二分QAQ
POJ 2104 K-th Number
题意:
给出一个序列,每次查询区间第k小
分析:
整体二分入门题?
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
#define inf 0x3f3f3f3f
using namespace std; const int maxn=+,maxm=+; int n,m,a[maxn],ans[maxm],tr[maxn]; struct M{
int x,y,k,id,flag;
M(int a=,int b=,int c=,int d=,int e=){
x=a,y=b,k=c,id=d,flag=e;
}
}q[maxm+maxn],q1[maxm+maxn],q2[maxm+maxn]; inline void add(int x,int y){
for(;x<=n;x+=x&(-x))
tr[x]+=y;
} inline int query(int x){
int res=;
for(;x;x-=x&(-x))
res+=tr[x];
return res;
} inline void solve(int L,int R,int l,int r){
if(L>R)
return;
if(l==r){
for(int i=L;i<=R;i++)
if(q[i].flag==)
ans[q[i].id]=l;
return;
}
int mid=(l+r)>>,l1=,l2=;
for(int i=L;i<=R;i++){
if(q[i].flag==){
if(q[i].x<=mid)
add(q[i].id,),q1[l1++]=q[i];
else
q2[l2++]=q[i];
}
else{
int lala=query(q[i].y)-query(q[i].x-);
if(lala>=q[i].k)
q1[l1++]=q[i];
else
q[i].k-=lala,q2[l2++]=q[i];
}
}
for(int i=;i<l1;i++)
if(q1[i].flag==)
add(q1[i].id,-);
memcpy(q+L,q1,sizeof(q[])*l1);
memcpy(q+L+l1,q2,sizeof(q[])*l2);
solve(L,L+l1-,l,mid);solve(L+l1,R,mid+,r);
} signed main(void){
while(scanf("%d%d",&n,&m)!=EOF){
memset(tr,,sizeof(tr));
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
q[i]=(M){a[i],,,i,};
}
for(int i=;i<=m;i++)
scanf("%d%d%d",&q[i+n].x,&q[i+n].y,&q[i+n].k),q[i+n].id=i,q[i+n].flag=;
solve(,n+m,-inf,inf);
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
}
return ;
}
BZOJ 1901: Zju2112 Dynamic Rankings
分析:
和上一题一样,就是把修改操作拆成删除和插入操作...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
#define inf 0x3f3f3f3f
using namespace std; const int maxn=+; int n,m,cnt,tot,tr[maxn],pre[maxn],ans[maxn]; char ch[]; struct M{
int x,y,k,id,flag;
}q[maxn*],q1[maxn*],q2[maxn*]; inline int read(void){
char ch=getchar();int f=,x=;
while(!(ch>=''&&ch<='')){
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
x=x*+ch-'',ch=getchar();
return x;
} inline void insert(int x,int y){
for(;x<=n;x+=x&(-x))
tr[x]+=y;
} inline int query(int x){
int res=;
for(;x;x-=x&(-x))
res+=tr[x];
return res;
} inline void solve(int L,int R,int l,int r){
if(L>R)
return;
if(l==r){
for(int i=L;i<=R;i++)
if(q[i].flag==)
ans[q[i].id]=l;
return;
}
int mid=(l+r)>>,l1=,l2=;
for(int i=L;i<=R;i++){
if(q[i].flag==){
if(q[i].x<=mid)
insert(q[i].id,q[i].y),q1[l1++]=q[i];
else
q2[l2++]=q[i];
}
else{
int lala=query(q[i].y)-query(q[i].x-);
if(lala>=q[i].k)
q1[l1++]=q[i];
else
q[i].k-=lala,q2[l2++]=q[i];
}
}
for(int i=;i<l1;i++)
if(q1[i].flag==)
insert(q1[i].id,-q1[i].y);
memcpy(q+L,q1,sizeof(q[])*l1);
memcpy(q+L+l1,q2,sizeof(q[])*l2);
solve(L,L+l1-,l,mid);solve(L+l1,R,mid+,r);
} signed main(void){
n=read(),m=read();tot=n;
for(int i=;i<=n;i++)
pre[i]=read(),q[i].x=pre[i],q[i].y=,q[i].k=,q[i].id=i,q[i].flag=;
for(int i=,x,y;i<=m;i++){
scanf("%s",ch);tot++;
if(ch[]=='Q')
q[tot].x=read(),q[tot].y=read(),q[tot].k=read(),q[tot].id=++cnt,q[tot].flag=;
else
x=read(),y=read(),q[tot].x=pre[x],q[tot].y=-,q[tot].k=,q[tot].id=x,q[tot].flag=,
pre[x]=y,q[++tot].x=y,q[tot].y=,q[tot].k=,q[tot].id=x,q[tot].flag=;
}
solve(,tot,,inf);
for(int i=;i<=cnt;i++)
printf("%d\n",ans[i]);
return ;
}//Cap ou pas cap. Cap.
BZOJ 3110: [Zjoi2013]K大数查询
分析:
还是一样的...只是把树状数组改成了线段树...
然而...虽然题水...但是我WA了半页...快读写错了...没有读入负数
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
#define int long long
using namespace std; const int maxn=+; int n,m,cnt,ans[maxn]; struct M{
int x,y,id,flag;
long long k;
}q[maxn],q1[maxn],q2[maxn]; struct Tree{
int l,r;
long long sum,lazy;
}tree[maxn<<]; inline long long longread(void){
char ch=getchar();int f=;long long x=;
while(!(ch>=''&&ch<='')){
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
x=x*+ch-'',ch=getchar();
return f*x;
} inline int intread(void){
char ch=getchar();int f=,x=;
while(!(ch>=''&&ch<='')){
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
x=x*+ch-'',ch=getchar();
return f*x;
} inline void build(int l,int r,int tr){
tree[tr].l=l,tree[tr].r=r,tree[tr].sum=,tree[tr].lazy=;
if(l==r)
return;
int mid=(l+r)>>;
build(l,mid,tr<<),build(mid+,r,tr<<|);
} inline void change(int l,int r,int val,int tr){//cout<<l<<" "<<r<<" "<<tree[tr].l<<" "<<tree[tr].r<<" "<<tr<<" ";
if(tree[tr].l==l&&tree[tr].r==r){
tree[tr].sum+=val*(r-l+);
tree[tr].lazy+=val;return;
}
int mid=(tree[tr].l+tree[tr].r)>>;//cout<<mid<<endl;
if(tree[tr].lazy)
change(tree[tr].l,mid,tree[tr].lazy,tr<<),change(mid+,tree[tr].r,tree[tr].lazy,tr<<|),tree[tr].lazy=;
if(r<=mid)
change(l,r,val,tr<<);
else if(l>mid)
change(l,r,val,tr<<|);
else
change(l,mid,val,tr<<),change(mid+,r,val,tr<<|);
tree[tr].sum=tree[tr<<].sum+tree[tr<<|].sum;
} inline long long query(int l,int r,int tr){//cout<<l<<" "<<r<<" "<<tree[tr].l<<" "<<tree[tr].r<<" "<<tr<<" ";
if(tree[tr].l==l&&tree[tr].r==r)
return tree[tr].sum;
int mid=(tree[tr].l+tree[tr].r)>>;//cout<<mid<<endl;
if(tree[tr].lazy)
change(tree[tr].l,mid,tree[tr].lazy,tr<<),change(mid+,tree[tr].r,tree[tr].lazy,tr<<|),tree[tr].lazy=;
if(r<=mid)
return query(l,r,tr<<);
else if(l>mid)
return query(l,r,tr<<|);
else
return query(l,mid,tr<<)+query(mid+,r,tr<<|);
} inline void solve(int L,int R,int l,int r){//cout<<L<<" "<<R<<" "<<l<<" "<<r<<endl;
if(L>R)
return;
if(l==r){
for(int i=L;i<=R;i++)
if(q[i].flag==)
ans[q[i].id]=l;
return;
}
int mid=(l+r)>>,l1=,l2=;
for(int i=L;i<=R;i++){//cout<<i<<endl;
if(q[i].flag==){//cout<<"***"<<endl;
if(q[i].k<=mid)
change(q[i].x,q[i].y,,),q1[l1++]=q[i];
else
q2[l2++]=q[i];
}
else{//cout<<"&&&"<<endl;
int lala=query(q[i].x,q[i].y,);//cout<<q[i].x<<" "<<q[i].y<<" "<<lala<<" "<<tree[1].sum<<endl;
if(lala>=q[i].k)
q1[l1++]=q[i];
else
q[i].k-=lala,q2[l2++]=q[i];
}
}//cout<<"lala"<<endl;
for(int i=;i<l1;i++)
if(q1[i].flag==)
change(q1[i].x,q1[i].y,-,);
// memcpy(q+L,q1,sizeof(q[0])*l1);
// memcpy(q+L+l1,q2,sizeof(q[0])*l2);
for(int i=;i<l1;i++)
q[L+i]=q1[i];
for(int i=;i<l2;i++)
q[L+l1+i]=q2[i];
solve(L,L+l1-,l,mid),solve(L+l1,R,mid+,r);
} signed main(void){
// freopen("sequence10.in","r",stdin);
// freopen("out.out","w",stdout);
n=intread();m=intread();cnt=;
// scanf("%lld%lld",&n,&m);
for(int i=,l,s,x,y;i<=m;i++){
l=intread();
// scanf("%lld",&l);
if(l==)
q[i].x=intread(),q[i].y=intread(),q[i].k=longread(),q[i].k=n-q[i].k+,q[i].flag=;
else
q[i].x=intread(),q[i].y=intread(),q[i].k=longread(),q[i].id=++cnt,q[i].flag=;
}build(,n,);solve(,m,,n);
for(int i=;i<=cnt;i++)
printf("%lld\n",n-ans[i]+);
return ;
}//Cap ou pas cap. Cap.
BZOJ 2527: [Poi2011]Meteors
还是板子题...感觉我要废了TAT...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
//by NeighThorn
using namespace std; const int maxn=+; int n,m,k,cnt,ans[maxn],need[maxn]; vector<int> v[maxn]; unsigned long long tr[maxn]; struct M{
int x,y,k,id,flag;
}q[maxn<<],q1[maxn<<],q2[maxn<<]; inline void insert(int x,int y){
for(;x<=m;x+=x&(-x))
tr[x]+=y;
} inline unsigned long long query(int x){
unsigned long long res=;
for(;x;x-=x&(-x))
res+=tr[x];
return res;
} inline void solve(int L,int R,int l,int r){
if(L>R)
return;
if(l==r){
for(int i=L;i<=R;i++)
if(q[i].flag==)
ans[q[i].id]=l;
return;
}
int mid=(l+r)>>,l1=,l2=;
for(int i=L;i<=R;i++){
if(q[i].flag==){
if(q[i].id<=mid)
insert(q[i].x,q[i].k),insert(q[i].y+,-q[i].k),q1[l1++]=q[i];
else
q2[l2++]=q[i];
}
else{
unsigned long long lala=;
for(int j=;j<v[q[i].id].size();j++)
lala+=query(v[q[i].id][j]);
if(lala>=q[i].k)
q1[l1++]=q[i];
else
q[i].k-=lala,q2[l2++]=q[i];
}
}
for(int i=;i<l1;i++)
if(q1[i].flag==)
insert(q1[i].x,-q1[i].k),insert(q1[i].y+,q1[i].k);
for(int i=;i<l1;i++)
q[L+i]=q1[i];
for(int i=;i<l2;i++)
q[L+l1+i]=q2[i];
solve(L,L+l1-,l,mid),solve(L+l1,R,mid+,r);
} signed main(void){
scanf("%d%d",&n,&m);
for(int i=,x;i<=m;i++)
scanf("%d",&x),v[x].push_back(i);
for(int i=;i<=n;i++)
scanf("%d",&need[i]);
scanf("%d",&k);
for(int i=,s,x,y;i<=k;i++){
scanf("%d%d%d",&x,&y,&s);
if(x<=y)
q[++cnt].x=x,q[cnt].y=y,q[cnt].k=s,q[cnt].flag=,q[cnt].id=i;
else
q[++cnt].x=x,q[cnt].y=m,q[cnt].k=s,q[cnt].flag=,q[cnt].id=i,
q[++cnt].x=,q[cnt].y=y,q[cnt].k=s,q[cnt].flag=,q[cnt].id=i;
}
for(int i=;i<=n;i++)
q[++cnt].k=need[i],q[cnt].id=i,q[cnt].flag=;
solve(,cnt,,k+);
for(int i=;i<=n;i++){
if(ans[i]==k+)
puts("NIE");
else
printf("%d\n",ans[i]);
}
return ;
}//Cap ou pas cap. Cap.
By NeighThorn
整体二分QAQ的更多相关文章
- BZOJ2527 [Poi2011]Meteors 整体二分 树状数组
原文链接http://www.cnblogs.com/zhouzhendong/p/8686460.html 题目传送门 - BZOJ2527 题意 有$n$个国家. 太空里有$m$个太空站排成一个圆 ...
- BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...
- 一篇自己都看不懂的CDQ分治&整体二分学习笔记
作为一个永不咕咕咕的博主,我来更笔记辣qaq CDQ分治 CDQ分治的思想还是比较简单的.它的基本流程是: \(1.\)将所有修改操作和查询操作按照时间顺序并在一起,形成一段序列.显然,会影响查询操作 ...
- 洛谷P3242 接水果 [HNOI2015] 整体二分
正解:整体二分+树状数组 解题报告: 传送门! 题目还是大概解释下?虽然其实是看得懂的来着,,, 大概就是说给一棵树.给定一些询问,每个询问都是说在两个点之间的路径上的子路径的第k大是什么 然后看到这 ...
- 洛谷P3250 网络 [HNOI2016] 整体二分
正解:整体二分+树状数组 解题报告: 传送门! 亲这里的建议是用整体二分呢 dbq最近看sd淘宝说话体看多了有点脑抽,,, 首先考虑如果是单组询问怎么做昂QAQ 考虑二分答案 对于所有比mid小的操作 ...
- BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
- [学习笔记] CDQ分治&整体二分
突然诈尸.png 这两个东西好像都是离线骗分大法... 不过其实这两个东西并不是一样的... 虽然代码长得比较像 CDQ分治 基本思想 其实CDQ分治的基本思想挺简单的... 大概思路就是长这样的: ...
- BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- P5163 WD与地图(整体二分+权值线段树)
传送门 细节要人命.jpg 这题思路太新奇了--首先不难发现可以倒着做变成加边,但是它还需要我们资瓷加边的同时维护强连通分量.显然加边之后暴力跑是不行的 然后有一个想法,对于一条边\((u,v)\), ...
随机推荐
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 奇异值分解(SVD)原理与在降维中的应用
奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...
- .NET 4.6.2正式发布带来众多特性
虽然大多数人的注意力都集中在.NET Core上,但与原来的.NET Framework相关的工作还在继续..NET Framework 4.6.2正式版已于近日发布,其重点是安全和WinForms/ ...
- 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器
LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...
- Consul 服务注册与服务发现
上一篇:Mac OS.Ubuntu 安装及使用 Consul 1. 服务注册 对 Consul 进行服务注册之前,需要先部署一个服务站点,我们可以使用 ASP.NET Core 创建 Web 应用程序 ...
- PHP与API讲解(一)
了解API: 在使用与创建自己的API之前我们需要先了解什么是API! API代表应用程序编程接口,而接口指的是一个特定的服务.一个应用程序或者其他程序的公共模块. 理解SOA(面向服务的架构):SO ...
- WebGIS中等值面展示的相关方案简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...
- C# 程序中嵌入百度地图
本例是对WinForm中使用百度地图的简要介绍.百度地图目前支持Android开发,IOS开发,Web开发,服务接口,具体可以参照'百度地图开放平台'. [动态加载百度地图]涉及到的知识点: WebB ...
- spring的BeanFactory加载过程
ApplicationContext spring = new ClassPathXmlApplicationContext("classpath*:spring/applicationCo ...
- PHP设计模式(八)桥接模式(Bridge For PHP)
一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 二.案例 1.模拟毛笔(转) 需求:现在需要准备三种粗细(大中小),并且有五种颜色的比 如果使用蜡 ...