显然可以dp:设f[i]为前i个人最多能分多少组,则f[i]=max{f[j]}+1 (cmax<=i-j<=dmin)。

  容易发现d的限制是一段连续区间,二分或者随便怎么搞都行。c则有点麻烦,考虑分治。找到区间中c最大的位置,处理左边区间再向右边(包括该位置)转移,最后处理右边区间(当然就是cdq分治)。

  考虑怎么转移。设当前区间为[l,r],分段点为k,处理的左边位置为i,右边位置j的限制区间为[aj,j-1],aj单调不降。若i能更新j,则满足i+ck<=j且i>=aj。显然j<l+ck或aj>=k的点是无法被转移到的。

  讨论一波。对于aj<=l的区间,开始一段右端点每次+1,查询一次后每次O(1)更新;后面一段都是整个区间转移,直接在线段树上打标记。这样保证了是O(较小区间),也就保证了分治的复杂度。a[j]>l的暴力在线段树上查询,因为对于每个j这只会出现一次,复杂度也很正确。

  不停地调分治结果发现线段树不停出锅,可能连线段树都不会写了,没救。(当然发现分治也出锅了

  非常卡空间。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 1000010
#define P 1000000007
int n,c[N],d[N],tree1[N<<];
priority_queue<int,vector<int>,greater<int> > q,qdel;
void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
struct data{int x,y;}tree[N<<],lazy[N<<],f[N];
void upd(data &a,data b)
{
if (b.x>a.x) a=b;
else if (b.x==a.x) inc(a.y,b.y);
}
void down(int k,int L,int R)
{
int mid=L+R>>;
upd(tree[k<<],(data){lazy[k].x,1ll*(mid-L+)*lazy[k].y%P});
upd(tree[k<<|],(data){lazy[k].x,1ll*(R-mid)*lazy[k].y%P});
upd(lazy[k<<],lazy[k]);
upd(lazy[k<<|],lazy[k]);
lazy[k]=(data){,};
}
data merge(data p,data q)
{
if (p.x<&&q.x<) return p;
if (p.x>q.x) return p;
else if (p.x<q.x) return q;
return (data){p.x,(p.y+q.y)%P};
}
data query(int k,int l,int r,int L,int R)
{
if (l>r) return (data){-N,};
if (L==l&&R==r) return tree[k];
if (lazy[k].x) down(k,L,R);
int mid=L+R>>;
if (r<=mid) return query(k<<,l,r,L,mid);
else if (l>mid) return query(k<<|,l,r,mid+,R);
else return merge(query(k<<,l,mid,L,mid),query(k<<|,mid+,r,mid+,R));
}
void modify(int k,int l,int r,data p,int L,int R)
{
if (l>r) return;
if (L==l&&R==r)
{
if (p.x>tree[k].x) tree[k].x=p.x,tree[k].y=1ll*p.y*(r-l+)%P,lazy[k]=p;
else if (p.x==tree[k].x) inc(tree[k].y,1ll*p.y*(r-l+)%P),lazy[k].x=p.x,inc(lazy[k].y,p.y);
return;
}
if (lazy[k].x) down(k,L,R);
int mid=L+R>>;
if (r<=mid) modify(k<<,l,r,p,L,mid);
else if (l>mid) modify(k<<|,l,r,p,mid+,R);
else modify(k<<,l,mid,p,L,mid),modify(k<<|,mid+,r,p,mid+,R);
tree[k]=merge(tree[k<<],tree[k<<|]);
}
int query2(int k,int l,int r,int L,int R)
{
if (L==l&&R==r) return tree1[k];
int mid=L+R>>;
if (r<=mid) return query2(k<<,l,r,L,mid);
else if (l>mid) return query2(k<<|,l,r,mid+,R);
else
{
int x=query2(k<<,l,mid,L,mid),y=query2(k<<|,mid+,r,mid+,R);
if (c[x]>c[y]) return x;else return y;
}
}
void build(int k,int l,int r)
{
if (l==r) {tree1[k]=l;tree[k]=f[l];return;}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tree1[k]=c[tree1[k<<]]>c[tree1[k<<|]]?tree1[k<<]:tree1[k<<|];
tree[k]=merge(tree[k<<],tree[k<<|]);
}
void pre()
{
int x=;
for (int i=;i<=n;i++)
{
q.push(d[i]);
while (!qdel.empty()&&q.top()==qdel.top()) q.pop(),qdel.pop();
while (q.top()+x<i) qdel.push(d[++x]);
tree1[i]=x;
}
while (!q.empty()) q.pop();
while (!qdel.empty()) qdel.pop();
for (int i=;i<=n;i++) d[i]=tree1[i];
build(,,n);
}
void solve(int l,int r)
{
if (l==r&&l)
{
data p=query(,l,l,,n);
if (p.x<=f[l].x) modify(,l,l,f[l],,n);
if (p.x>=f[l].x) upd(f[l],p);
}
if (l>=r) return;
int k=query2(,l+,r,,n);
solve(l,k-);
if (d[k]<k)
{
data p=query(,l,k-c[k]-,,n);
for (int i=max(l+c[k],k);i<=r&&d[i]<=l&&i<=k-+c[k];i++)
{
upd(p,f[i-c[k]]);
upd(f[i],(data){p.x+,p.y});
}
int L=k,R=r,t=k-;
while (L<=R)
{
int mid=L+R>>;
if (d[mid]<=l) t=mid,L=mid+;
else R=mid-;
}
modify(,k+c[k],t,(data){p.x+,p.y},,n);
for (int i=t+;d[i]<=k-&&i<=r;i++)
{
p=query(,d[i],min(i-c[k],k-),,n);
upd(f[i],(data){p.x+,p.y});
}
}
solve(k,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3711.in","r",stdin);
freopen("bzoj3711.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++) c[i]=read(),d[i]=read();
f[].x=,f[].y=;
for (int i=;i<=n;i++) f[i].x=-N,f[i].y=;
pre();
solve(,n);
if (f[n].x>=) cout<<f[n].x<<' '<<f[n].y<<endl;
else cout<<"NIE";
return ;
}

BZOJ3711 PA2014Druzyny(动态规划+cdq分治+线段树)的更多相关文章

  1. ACdream1157 Segments(CDQ分治 + 线段树)

    题目这么说的: 进行如下3种类型操作:1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]2)C i (1-base) 删除第i条增加的线段, ...

  2. hdu 4366 Successor - CDQ分治 - 线段树 - 树分块

    Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty an ...

  3. HDU 6183 Color it cdq分治 + 线段树 + 状态压缩

    Color it Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Pro ...

  4. bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)

    Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...

  5. Codechef SEP14 QRECT cdq分治+线段树

    题意 支持删除矩阵.插入矩阵.查询当前矩阵与之前有多少个矩阵相交 算相交的时候容斥一下:相交矩形数 = 总矩形数-X轴投影不相交的矩形数-Y轴投影不相交的矩形数-XY轴投影下都不相交的矩形数 最后一项 ...

  6. [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)

    [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...

  7. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  8. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  9. 【BZOJ4372】烁烁的游戏 动态树分治+线段树

    [BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...

随机推荐

  1. nowcoder wannafly 25 E:01串

    E:01 串 链接 分析: 线段树维护转移矩阵.每个节点是一个矩阵,区间内的矩阵乘起来就是答案矩阵.矩阵乘法满足结合律,所以线段树维护. 代码: #include<cstdio> #inc ...

  2. 洛谷2612&&bzoj2817 [ZJOI2012]波浪

    洛谷2612&&bzoj2817 [ZJOI2012]波浪 原题链接 题解 因为有abs不太好搞,考虑拆掉abs. 生成排列的方法之一:n个空位,从1到n一次插入一个空位. 这样搞的话 ...

  3. PL/SQL编辑数据"这些查询结果不可更新,请包括ROWID或使用SELECT...FOR UPDATE获得可更新结果"处理

    只要有人用了: select t.* from 表名  t where 字段=xxx  for update 而不是: select t.rowid,t.* from 表名  t where 字段=x ...

  4. IIS解决上传文件大小限制

    目的:通过配置文件和IIS来解决服务器对上传文件大小的限制 1:修改配置文件(默认为4M 值的大小根据自己情况进行修改) <httpRuntime  maxRequestLength=" ...

  5. Git生成多个ssh key

    在实际的工作中, 有可能需要连接多个远程仓库, 例如我想连接私有仓库.GitLab官网.GitHub官网, 那么同一台电脑就要生成多个ssh key: ssh-keygen -t rsa -C &qu ...

  6. Hexo+gitment

    Gitment是一个基于GitHub问题的评论系统,可以在没有任何服务器端实现的前端使用. 演示页面 中文简介 特征 入门 方法 定制 关于安全 特征 GitHub登录 Markdown / GFM支 ...

  7. CentOS 6.8 安装JDK8

    JDK安装 1.查看环境是否有默认jdk,输入命令: rpm -qa | grep jdk 如果有默认jdk,可以使用 yum remove 删除 2.进入系统根目录,创建developer文件夹 3 ...

  8. Python基础入门(模块和包)

    1 模块 1.1 什么是模块 在 Python 中,一个 .py 文件就称之为一个模块(Module). 我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模块就是函数功能的扩展.为什么这 ...

  9. K8S-RedisCluster搭建

    简介         Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接, mastart节点之间存放的数据并不是相同的,只是其中的一部分,当我们请 ...

  10. 从零开始的Python学习Episode 7——文件基本操作

    文件基本操作 一.打开文件 f = open('11','r')#open('file path','mode') 创建一个文件对象 文件有多种打开模式: 1. 'r':新建一个文件对象以只读方式打开 ...