http://www.lydsy.com/JudgeOnline/problem.php?id=3110
题意:
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
线段树套线段树,外面是权值,每个节点上的线段树是位置,
比如,如果在1~4位置加入5 就是把整个线段树中有5的log个节点,
每个节点的1~4这log区间上++。。。。
然后每次询问的时候,二分答案,
比如权值二分到3就是求1~3中有多少个在询问的区间里,还是log个节点,
每个节点跑log个得到对应区间上的个数总和
这样会tle&& mle,代码如下:
/*
线段树套线段树,外面是权值,每个节点上的线段树是位置,
比如,如果在1~4位置加入5 就是把整个线段树中有5的log个节点,
每个节点的1~4这log区间上++。。。。
然后每次询问的时候,二分答案,
比如权值二分到3就是求1~3中有多少个在询问的区间里,还是log个节点,
每个节点跑log个得到对应区间上的个数总和
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int maxn = 3e7+10;
const int maxm = 50000*4+10;
int root[maxm],N,Q;
struct pos_Tree{
int lon,ron,add;
unsigned int _size;
void init(){
lon = ron = add = _size = 0;
}
};
class segment_tree{
public:
pos_Tree tree[maxn];LL cnt;
void push_down(int k,int m,int l,int r){
if(tree[k].add == 0) return ;
if(tree[k].lon == 0){
cnt++;tree[k].lon = cnt;//tree[cnt].l = l;tree[cnt].r = (l+r)/2;
tree[cnt]._size = (m-(m/2))*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].lon]._size +=(m-(m/2))*tree[k].add,tree[tree[k].lon].add += tree[k].add;
if(tree[k].ron == 0){
cnt++;tree[k].ron = cnt;//tree[cnt].l = (l+r)/2+1;tree[cnt].r = r;
tree[cnt]._size = (m/2)*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].ron]._size +=(m/2)*tree[k].add,tree[tree[k].ron].add += tree[k].add;
tree[k].add = 0;
}
void push_up(int k,int ln,int rn){
tree[k]._size = tree[ln]._size+tree[rn]._size;
}
void _insert(int &k,int L,int R,int l,int r,int rt){
if(k == 0){
cnt++;tree[cnt].init();k = cnt;//tree[k].l = l;tree[k].r = r;
}
if(L <= l && R >= r){
tree[k].add++;tree[k]._size += r-l+1;
return ;
}
push_down(k,r-l+1,l,r);
int m = (l+r)>>1;
if(m >= L) _insert(tree[k].lon,L,R,lson);
if(m < R) _insert(tree[k].ron,L,R,rson);
push_up(k,tree[k].lon,tree[k].ron);
}
LL query(int k,int L,int R,int l,int r,int rt){
if(l >= L && r <= R){
return tree[k]._size;
}
push_down(k,r-l+1,l,r);
//cout <<" k = "<<k<<endl;
int m = (l+r)/2;
LL ans = 0;
if(m >= L && tree[k].lon) ans += query(tree[k].lon,L,R,lson);
if(m < R && tree[k].ron) ans += query(tree[k].ron,L,R,rson);
return ans;
}
}pos_tree;//区间线段树
void build(int l,int r,int rt){
root[rt] = 0;
if(l == r) return ;
int m = (l+r)>>1;
build(lson);
build(rson);
}
void val_insert(int a,int b,int pos,int l,int r,int rt){
if(pos >= l && pos <= r){
pos_tree._insert(root[rt],a,b,1,N,1);
}
if(l == r) return ;
int m = (l+r)>>1;
if(pos <= m) val_insert(a,b,pos,lson);
else val_insert(a,b,pos,rson);
}
int _in(int mid,int l,int r,int rt){
if(l == r && l == mid) return root[rt];
int m = (l+r)>>1;
if(mid <= m) return _in(mid,lson);
else return _in(mid,rson);
}
LL check(int L,int R,int posa,int posb,int l,int r,int rt){
if(L <= l && R >= r){
if(root[rt] == 0) return 0;
LL ans = pos_tree.query(root[rt],posa,posb,1,N,1);
return ans ;
}
LL ans = 0;
int m = (l+r)>>1;
if(m >= L) ans += check(L,R,posa,posb,lson);
if(m < R) ans += check(L,R,posa,posb,rson);
return ans;
}
int bs(int posa,int posb,int c){
int l = 1,r = N,ans = 100000000;
while(l <= r){
int mid = (l+r)>>1;
LL pp = check(1,mid,posa,posb,1,N,1);
if( pp >= c){
//1~mid权值中到了c个就是可能得解,多了就缩小范围
if(_in(mid,1,N,1))//mid是否是出现了得权值
ans = min(ans,mid);
r = mid-1;
}
else l = mid+1;
}
return ans;
}
int op,a,b,c;
void sov(){
pos_tree.cnt = 0;
for(int i = 1; i<= Q ; i++){
scanf("%d",&op);
if(op == 1){
scanf("%d%d%d",&a,&b,&c);
if(a > b) swap(a,b);
c = N-c+1;
val_insert(a,b,c,1,N,1);
}
else{
scanf("%d%d%d",&a,&b,&c);
if(a > b) swap(a,b);
printf("%d\n",N-bs(a,b,c)+1);
}
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&N,&Q)){
build(1,N,1);
sov();
}
return 0;
}
/*
7 100
1 1 5 2
1 2 7 3
1 3 5 2
1 1 1 1
2 1 3 2
2 1 3 3
2 1 3 7
2 1 7 5
2 1 7 7
2 2 3 2
2 1 1 1
2 1 1 2
2 3 5 3
2 3 4 5
2 1 5 2
2 2 7 2
2 3 5 2
2 2 2 1
*/
改成树状数组,mle问题解决,时间复杂度仍然有logloglog
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int maxn = 3e7+10;
const int maxm = 50000+10;
int root[maxm],N,Q;
struct pos_Tree{
int lon,ron,add;
unsigned int _size;
void init(){
lon = ron = add = _size = 0;
}
};
class segment_tree{
public:
pos_Tree tree[maxn];LL cnt;
void push_down(int k,int m,int l,int r){
if(tree[k].add == 0) return ;
if(tree[k].lon == 0){
cnt++;tree[k].lon = cnt;//tree[cnt].l = l;tree[cnt].r = (l+r)/2;
tree[cnt]._size = (m-(m/2))*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].lon]._size +=(m-(m/2))*tree[k].add,tree[tree[k].lon].add += tree[k].add;
if(tree[k].ron == 0){
cnt++;tree[k].ron = cnt;//tree[cnt].l = (l+r)/2+1;tree[cnt].r = r;
tree[cnt]._size = (m/2)*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].ron]._size +=(m/2)*tree[k].add,tree[tree[k].ron].add += tree[k].add;
tree[k].add = 0;
}
void push_up(int k,int ln,int rn){
tree[k]._size = tree[ln]._size+tree[rn]._size;
}
void _insert(int &k,int L,int R,int l,int r,int rt){
if(k == 0){
cnt++;tree[cnt].init();k = cnt;//tree[k].l = l;tree[k].r = r;
}
if(L <= l && R >= r){
tree[k].add++;tree[k]._size += r-l+1;
return ;
}
push_down(k,r-l+1,l,r);
int m = (l+r)>>1;
if(m >= L) _insert(tree[k].lon,L,R,lson);
if(m < R) _insert(tree[k].ron,L,R,rson);
push_up(k,tree[k].lon,tree[k].ron);
}
LL query(int k,int L,int R,int l,int r,int rt){
if(l >= L && r <= R){
return tree[k]._size;
}
push_down(k,r-l+1,l,r);
//cout <<" k = "<<k<<endl;
int m = (l+r)/2;
LL ans = 0;
if(m >= L && tree[k].lon) ans += query(tree[k].lon,L,R,lson);
if(m < R && tree[k].ron) ans += query(tree[k].ron,L,R,rson);
return ans;
}
}pos_tree;//Çø¼äÏ߶ÎÊ÷
int lowbit(int x){
return x&(-x);
}
void add(int pos,int a,int b){
for(int i = pos ; i <= N ;i += lowbit(i)){
pos_tree._insert(root[i],a,b,1,N,1);
}
}
LL check(int pos,int posa,int posb){
LL sum = 0;
for(int i = pos; i>0 ;i-=lowbit(i)){
sum += pos_tree.query(root[i],posa,posb,1,N,1);
}
return sum;
}
int bs(int posa,int posb,int k){
int l = 1,r = N;
while(l <= r){
int mid = (l+r)>>1;
LL cm = check(mid,posa,posb);//1~mid
LL cm1 = check(mid-1,posa,posb);//1~mid-1
if(cm >= k && cm1 < k){
return mid;
}
else if(cm >= k) r = mid-1;
else l = mid+1; //cm<k&&cm1<k
}
}
int op,a,b,c;
void sov(){
pos_tree.cnt = 0;
for(int i = 1; i<= Q ; i++){
scanf("%d",&op);
if(op == 1){
scanf("%d%d%d",&a,&b,&c);
c = N-c+1;
if(a > b) swap(a,b);
add(c,a,b);
}
else{
scanf("%d%d%d",&a,&b,&c);
if(a > b) swap(a,b);
printf("%d\n",N-bs(a,b,c)+1);
}
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&N,&Q)){
sov();
}
}
超时?不用二分答案,在线段树上,直接判断大的数够不够,不够的话,往左跑看加上多少左边的可以到达要求个,够的话就往右递归,看最小的范围(l==r)时候,ac代码:
/*
线段树套线段树,外面是权值,每个节点上的线段树是位置,
比如,如果在1~4位置加入5 就是把整个线段树中有5的log个节点,
每个节点的1~4这log区间上++。。。。
然后每次询问的时候,
每个节点跑log个得到对应区间上的个数总和
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int maxn = 3e7+10;
const int maxm = 50000*4+10;
int root[maxm],N,Q;
struct pos_Tree{
int lon,ron,add;
unsigned int _size;
void init(){
lon = ron = add = _size = 0;
}
};
class segment_tree{
public:
pos_Tree tree[maxn];LL cnt;
void push_down(int k,int m,int l,int r){
if(tree[k].add == 0) return ;
if(tree[k].lon == 0){
cnt++;tree[k].lon = cnt;//tree[cnt].l = l;tree[cnt].r = (l+r)/2;
tree[cnt]._size = (m-(m/2))*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].lon]._size +=(m-(m/2))*tree[k].add,tree[tree[k].lon].add += tree[k].add;
if(tree[k].ron == 0){
cnt++;tree[k].ron = cnt;//tree[cnt].l = (l+r)/2+1;tree[cnt].r = r;
tree[cnt]._size = (m/2)*tree[k].add;tree[cnt].add = tree[k].add;
}
else tree[tree[k].ron]._size +=(m/2)*tree[k].add,tree[tree[k].ron].add += tree[k].add;
tree[k].add = 0;
}
void push_up(int k,int ln,int rn){
tree[k]._size = tree[ln]._size+tree[rn]._size;
}
void _insert(int &k,int L,int R,int l,int r,int rt){
if(k == 0){
cnt++;tree[cnt].init();k = cnt;//tree[k].l = l;tree[k].r = r;
}
if(L <= l && R >= r){
tree[k].add++;tree[k]._size += r-l+1;
return ;
}
push_down(k,r-l+1,l,r);
int m = (l+r)>>1;
if(m >= L) _insert(tree[k].lon,L,R,lson);
if(m < R) _insert(tree[k].ron,L,R,rson);
push_up(k,tree[k].lon,tree[k].ron);
}
LL query(int k,int L,int R,int l,int r,int rt){
if(l >= L && r <= R){
return tree[k]._size;
}
push_down(k,r-l+1,l,r);
//cout <<" k = "<<k<<endl;
int m = (l+r)/2;
LL ans = 0;
if(m >= L && tree[k].lon) ans += query(tree[k].lon,L,R,lson);
if(m < R && tree[k].ron) ans += query(tree[k].ron,L,R,rson);
return ans;
}
}pos_tree;//区间线段树
void build(int l,int r,int rt){
root[rt] = 0;
if(l == r) return ;
int m = (l+r)>>1;
build(lson);
build(rson);
}
void val_insert(int a,int b,int pos,int l,int r,int rt){
if(pos >= l && pos <= r){
pos_tree._insert(root[rt],a,b,1,N,1);
}
if(l == r) return ;
int m = (l+r)>>1;
if(pos <= m) val_insert(a,b,pos,lson);
else val_insert(a,b,pos,rson);
}
LL check(int posa,int posb,int num,int l,int r,int rt){
if(l == r) return l;
int m = (l+r)>>1,ans;
LL n1 = (root[rt*2+1] == 0)?0:pos_tree.query(root[rt*2+1],posa,posb,1,N,1);
if(n1 < num) ans = check(posa,posb,num-n1,lson);
else ans = check(posa,posb,num,rson);
return ans;
}
int op,a,b,c;
void sov(){
pos_tree.cnt = 0;
for(int i = 1; i<= Q ; i++){
scanf("%d",&op);
if(op == 1){
scanf("%d%d%d",&a,&b,&c);
if(a > b) swap(a,b);
val_insert(a,b,c,1,N,1);
}
else{
scanf("%d%d%d",&a,&b,&c);
if(a > b) swap(a,b);
printf("%d\n",check(a,b,c,1,N,1));
}
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&N,&Q)){
build(1,N,1);
sov();
}
return 0;
}
/*
7 100
1 1 5 2
1 2 7 3
1 3 5 2
1 1 1 1
2 1 3 2
2 1 3 3
2 1 3 7
2 1 7 5
2 1 7 7
2 2 3 2
2 1 1 1
2 1 1 2
2 3 5 3
2 3 4 5
2 1 5 2
2 2 7 2
2 3 5 2
2 2 2 1
*/
文章浏览阅读449次。精选30+云产品,助力企业轻松上云!>>> Hado..._hadoop1.0和2.0项目结构
文章浏览阅读270次。首先是安装ROS,我所用的ubuntu16.04,所安装的ROS是kinetic版本,安装请参考:ubuntu16.04安装ROS1.管理环境变量在前面的安装过程中,配置亮环境,此时来查看ROS环境是否配置成功:export | grep ROS植入命令之后会出现如下信息:如果没有就需要重新输入添加环境变量的命令。2.创建ROS工作空间通过创建ros工作站,也..._接下来首先source一下新生成的setup.*sh文件:
文章浏览阅读5.4k次,点赞16次,收藏171次。一、Lattice(Frenet)二、EM三、Opt(OSQP)/IPOPT汇总四、Hybrid A*/圆弧Lattice以上算法结合感知决策等框架,是否能覆盖大多数场景?L2/L4,辅助驾驶、矿区、环卫、Robotaxi、泊车、无人接驳车、农用、Robobus、物流配送、Robotruck新势力、Tier1、计算平台?工业界的仿真、量产、数据?..._apollo古月居
文章浏览阅读731次。先简单介绍一下矩阵乘法求斐波那契数列的原理f(n) 是第n项的值。f(1)= 1; f(2) =1;f(n)= f(n-1) + (n-2)下面的介绍是我从网上查到了,收益匪浅。分两步推导: 问题的求解就变成的解决,而幂的求可用二分法来求。二分法可用递归和非递归来求:下面是代码:定义矩阵struct matrix //定义2*2的矩阵&nb_矩阵乘法算波拉契法吗
文章浏览阅读3.3w次,点赞5次,收藏10次。报错信息如下[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1056)主要是下面两种连接邮件服务器的误操作引起的(是否开启了TLS)smtplib.SMTP(self.host, self.port, timeout=300) 【TLS 禁用时使用】或smtplib.SMTP_SSL(self.host, self...._ssl.sslerror: [ssl: wrong_version_number] wrong version number (_ssl.c:1056)
文章浏览阅读1.1k次。代码.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>确认订单</title> <link rel="stylesheet" href="./l_html移动端好看的支付界面
文章浏览阅读2.3w次,点赞36次,收藏102次。一、我们发现ACM的latex模板中会有ACM Reference Format信息,如下:投稿时,可以使用如下的方法将其去掉,在 \documentclass[sigconf]{acmart}下面直接添加这几行即可去掉\settopmatter{printacmref=false} % Removes citation information below abstract\re..._settopmatter
文章浏览阅读2.5k次。1.最外层div加上 -webkit-overflow-scrolling属性,解决ios滑动不流畅.div {-webkit-overflow-scrolling: touch;}2.外层div里面的所有元素添加 -webkit-transform: translateZ(0px)属性,解决滑动时出现的空白(即图片不显示).div > * {-webkit-transform:..._ios h5 卡
文章浏览阅读1.1k次。numpy.random.seed, torch.manual_seed使用_args.seed % 2**32
文章浏览阅读1.1k次。原文:http://mobile.51cto.com/aprogram-387591.htm/**_android 将assert文件写入sd卡中
文章浏览阅读434次。属性动画是3.0推出的新特性,和View动画不同,他对对象进行了扩展,属性动画可以对任何对象做动画.在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化控制,只控制一个对象的属性值,使用多个ObjectAnimator组合到AnimatorSet中形成一个动画. 在这里说明,动画默认的时间间隔是300ms,默认_android 属性动画 缩放代码
文章浏览阅读5.5k次。系统日志的重要性 与一个简单的算法不同,一个合格的系统不仅仅要求具有运行的高效和计算的准确,同时又必须兼顾稳定性、可靠性。其次,对于开发人员来说,又必须具有可拓展性和可维护性。各方面都必须很完善,这样的一个系统才能称得上是一个合格完美的系统。简单的站在开发人员的角度分析,比较重视的是系统的可维护性,毕竟开发人员直面的是系统的代码实现。一个代码结构冗杂、模块设计混乱、命名“异想天开”的系统对于..._系统日志作用