题面:

模拟93考得并不理想,二维偏序没看出来,然而看出来了也不会打

序列:

对a,b数列求前缀和,那么题意转化为了满足$suma[i]>=suma[j]$且$sumb[i]>=sumb[j]$的最大$i-j+1$值

那么就是二维偏序,那么按a排序,把b塞到树状数组里

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<ctime>
#define int long long
using namespace std;
const int MAXN=5e5+;
int n,ans=,sta[MAXN],top=;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
x=(x<<)+(x<<)+ch-'';
ch=getchar();
}
return x*f;
}
struct node{
int a,b,id;
friend bool operator < (node p,node q){
return p.a==q.a?p.b<q.b:p.a<q.a;
}
}val[MAXN];
int lowbit(int x){
return x&-x;
}
int c[MAXN];
void update(int pos,int val){
for(int i=pos;i<=top;i+=lowbit(i)){
c[i]=min(c[i],val);
}
}
int query(int pos){
int res=0x3f3f3f3f3f3f3f3f;
for(int i=pos;i>;i-=lowbit(i)){
res=min(res,c[i]);
}
return res;
}
signed main(){
n=read();
for(int i=;i<=n;++i){
val[i].a=read();
val[i].a+=val[i-].a;
val[i].id=i;
}
for(int i=;i<=n;++i){
val[i].b=read();
val[i].b+=val[i-].b;
sta[++top]=val[i].b;
}
sort(val+,val+n+);
sort(sta+,sta+top+);
top=unique(sta+,sta+top+)-sta-;
for(int i=;i<=n;++i)
val[i].b=lower_bound(sta+,sta+top+,val[i].b)-sta;
memset(c,0x3f,sizeof(c));
for(int i=;i<=n;++i){
int res=query(val[i].b);
ans=max(ans,val[i].id-res);
update(val[i].b,val[i].id);
}
printf("%lld\n",ans);
return ;
}

二叉搜索树:

区间dp,设f[i,j]表示考虑区间[i,j]的贡献,则f[i,j]=min(f[i,k-1]+f[k+1,j]+a[i,j])

然后发现k有决策单调性,所以我们记录一个dp数组,dp[i,j]表示f[i,j]是由那一个k转移而来,然后对于每一个i,j,枚举k的范围就变成了dp[i+1,j]到dp[i,j-1]

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define int long long
using namespace std;
const int MAXN=;
int n,ans=,sum[MAXN],f[MAXN][MAXN],dp[MAXN][MAXN];
struct node{
int x,id;
friend bool operator < (node p,node q){
return p.x==q.x?p.id>q.id:p.x>q.x;
}
}a[MAXN];
int min(int p,int q){
return p<q?p:q;
}
signed main(){
memset(f,0x3f,sizeof(f));
scanf("%lld",&n);
for(int i=;i<=n;++i){
scanf("%lld",&a[i].x);
a[i].id=i;
sum[i]=sum[i-]+a[i].x;
f[i][i]=a[i].x;
dp[i][i]=i;
}
for(int i=;i<=n+;++i){
for(int j=;j<i;++j) f[i][j]=;
}
for(int l=;l<=n;++l){
for(int i=;i+l-<=n;++i){
int j=i+l-;
for(int k=dp[i][j-];k<=dp[i+][j];++k){
if(f[i][j]>=f[i][k-]+f[k+][j]+sum[j]-sum[i-]){
f[i][j]=f[i][k-]+f[k+][j]+sum[j]-sum[i-];
dp[i][j]=k;
}
}
}
}
printf("%lld\n",f[][n]);
return ;
}

走路:分治消元

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXM=1e5+,mod=;
int n,m,du[],cnt[][],inv[MAXM],a[][],ans[];
int q_pow(int a,int b,int p){
int res=;
while(b){
if(b&) res=res*a%p;
a=a*a%p;
b>>=;
}
return res;
}
void solve(int l,int r){
if(l==r){
ans[l]=(a[][n+]+mod)%mod;
return ;
}
int t[][];
for(int i=;i<=n;++i){
for(int j=;j<=n+;++j)
t[i][j]=a[i][j];
}
int mid=(l+r)>>;
for(int x=mid+;x<=r;++x){
int invv=q_pow(a[x][x],mod-,mod);
for(int i=;i<=n+;++i) (a[x][i]*=invv)%=mod;
for(int i=;i<=n;++i){
if(i==x) continue;
invv=a[i][x];
for(int j=l;j<=r;++j){
a[i][j]=(a[i][j]-a[x][j]*invv+mod)%mod;
}
a[i][n+]=(a[i][n+]-a[x][n+]*invv+mod)%mod;
}
}
solve(l,mid);
for(int i=;i<=n;++i){
for(int j=;j<=n+;++j)
a[i][j]=t[i][j];
}
for(int x=l;x<=mid;++x){
int invv=q_pow(a[x][x],mod-,mod);
for(int i=;i<=n+;++i) (a[x][i]*=invv)%=mod;
for(int i=;i<=n;++i){
if(i==x) continue;
invv=a[i][x];
for(int j=l;j<=r;++j){
a[i][j]=(a[i][j]-a[x][j]*invv%mod+mod)%mod;
}
a[i][n+]=(a[i][n+]-a[x][n+]*invv%mod+mod)%mod;
}
}
solve(mid+,r);
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=,u,v;i<=m;++i){
scanf("%lld%lld",&u,&v);
++du[u],++cnt[u][v];
}
for(int i=;i<=m;++i) inv[i]=q_pow(i,mod-,mod);
for(int i=;i<=n;++i){
for(int j=;j<=n;++j){
a[i][j]=cnt[i][j]*q_pow(du[i],mod-,mod)%mod;
}
a[i][n+]=-;
--a[i][i];
}
solve(,n);
for(int i=;i<=n;++i) printf("%lld\n",ans[i]);
return ;
}

csps模拟93序列,二叉搜索树,走路题解的更多相关文章

  1. 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历

    二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历   二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则 ...

  2. 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历

    二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根 ...

  3. [CSP-S模拟测试]:二叉搜索树(DP+贪心)

    题目传送门(内部题99) 输入格式 第一行一个整数$n$,第二行$n$个整数$x_1\sim x_n$. 输出格式 一行一个整数表示答案. 样例 样例输入: 58 2 1 4 3 样例输出: 数据范围 ...

  4. 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】

    开一个指针数组,中序遍历这个二叉搜索树,将节点的指针依次保存在数组里, 然后寻找两处逆序的位置, 中序便利里BST得到的是升序序列 ++++++++++++++++++++++++++++++++++ ...

  5. 【剑指offer】二叉搜索树转双向链表,C++实现

    原创博文,转载请注明出处! # 题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二叉树节点的定义 struct TreeNod ...

  6. 剑指Offer面试题:22.二叉搜索树的后序遍历序列

    一.题目:二叉搜索树的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如在下面 ...

  7. Interview----判断整数序列是否是二叉搜索树的后序遍历结果

    题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果:   ...

  8. (剑指Offer)面试题24:二叉搜索树的后序遍历序列

    题目: 输入一个整数数组,判断该数组是不是某个二叉搜索树的后序遍历的结果,如果是则返回true,否则返回false. 假设输入的数组的任意两个数字都互不相同. 思路: 根据二叉搜索树的后序遍历特点,很 ...

  9. P140、面试题24:二叉搜索树的后序遍历序列

    题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 测试用例: 1)功能测试(输入的后序遍历的序列 ...

随机推荐

  1. AVR446步进电机算法推导及应用

    https://blog.csdn.net/Renjiankun/article/details/80513839?utm_source=copy

  2. Linux特殊位SUID、SGID、SBIT

    Linux特殊位SUID.SGID.SBIT 前言 Linux中的文件权限一般有x.w.r,在某个情况下有需要用到s.t,即特殊位. 进程运行时能够访问哪些资源或文件,不取决于进程文件的属主属组,而是 ...

  3. 磁盘设备在 Linux 下的表示方法

    在 Linux 系统中磁盘设备文件的命名规则为: 主设备号 + 次设备号 + 磁盘分区号 对于目前常见的磁盘,一般表示为: sd[a-z]x 主设备号代表设备的类型,相同的主设备号表示同类型的设备. ...

  4. mimikaz获取明文密码

    一.windows2008以上不保存明文密码解决办法 mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords& ...

  5. usermod -修改使用者帐号

    总览 SYNOPSIS usermod [-c comment] [-d home_dir [-m]] [-e expire_date] [-f inactive_time] [-g initial_ ...

  6. PagedLOD模型对象选择关键技术点

    DatabaseCacheReadCallback这个类继承ReadCallback,在相交的测试中,场景可能有PagedLOD,而计算相交过程中,PagedLOD不是精度最高的节点,这样计算的就不准 ...

  7. 关于第一次web前端面试的记录

    最近参加了一场面试,感觉自己题目都懂,但是说起来就是有点说不明白,所以写个博客整理以下吧.答案不少不是面试时回答的答案,只是整理一下可行答案 1. 如图1,使B相对于A垂直居中 图1 <styl ...

  8. Go 静态类型声明

    Go 静态类型声明 package main import "fmt" func main() { var x float64 x = 20.0 fmt.Println(x) fm ...

  9. 依赖背包变形——hdu4003

    思维性比较强,代码挺简单的,dp[u][j]表示在u子树下安排j个机器人,让其不回u 注意转移时的初始值 /* dp[u][j]为在子树u有j个机器人不回来 */ #include<bits/s ...

  10. Centos7.5安装kafka集群

    Tags: kafka Centos7.5安装kafka集群 Centos7.5安装kafka集群 主机环境 软件环境 主机规划 主机安装前准备 安装jdk1.8 安装zookeeper 安装kafk ...