csps模拟93序列,二叉搜索树,走路题解
题面:
模拟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序列,二叉搜索树,走路题解的更多相关文章
- 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历
二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历 二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则 ...
- 二叉搜索树的结构(30 分) PTA 模拟+字符串处理 二叉搜索树的节点插入和非递归遍历
二叉搜索树的结构(30 分) 二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根 ...
- [CSP-S模拟测试]:二叉搜索树(DP+贪心)
题目传送门(内部题99) 输入格式 第一行一个整数$n$,第二行$n$个整数$x_1\sim x_n$. 输出格式 一行一个整数表示答案. 样例 样例输入: 58 2 1 4 3 样例输出: 数据范围 ...
- 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】
开一个指针数组,中序遍历这个二叉搜索树,将节点的指针依次保存在数组里, 然后寻找两处逆序的位置, 中序便利里BST得到的是升序序列 ++++++++++++++++++++++++++++++++++ ...
- 【剑指offer】二叉搜索树转双向链表,C++实现
原创博文,转载请注明出处! # 题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二叉树节点的定义 struct TreeNod ...
- 剑指Offer面试题:22.二叉搜索树的后序遍历序列
一.题目:二叉搜索树的后序遍历序列 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 例如在下面 ...
- Interview----判断整数序列是否是二叉搜索树的后序遍历结果
题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: ...
- (剑指Offer)面试题24:二叉搜索树的后序遍历序列
题目: 输入一个整数数组,判断该数组是不是某个二叉搜索树的后序遍历的结果,如果是则返回true,否则返回false. 假设输入的数组的任意两个数字都互不相同. 思路: 根据二叉搜索树的后序遍历特点,很 ...
- P140、面试题24:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. 测试用例: 1)功能测试(输入的后序遍历的序列 ...
随机推荐
- 2018-8-10-win10-uwp-反射
title author date CreateTime categories win10 uwp 反射 lindexi 2018-08-10 19:17:19 +0800 2018-2-13 17: ...
- Centos7 PXE Server Install Script
#安装前配置好centos和epel yum源 #网卡ip和localip一致 localip="192.168.88.200" eth_name='eth0' dnsmasq_i ...
- Windows server 2016 / Windows 10关于域管理员帐号权限不足的问题
今天在测试windows server 2016的域创建时,当安装结束之后,发现使用Administrator用户进行操作时,被提示了权限不足这个问题.于是我在百度上查找了一番之后,找到了解决方法. ...
- selenium+plantomJS
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 流程框架: 1.搜索关键词,利用selenium驱动浏览器搜索关键词,查 ...
- Python Faker的使用 及 常用函数的查询
安装faker pip install faker faker的使用 引用:from faker import Faker 初始化:f=Faker(locale='zh_CN') # 默认是en_U ...
- 使用 SpringBoot 配置发送邮件功能
1.使用 SpringBoot 配置发送邮件功能 项目总体结构 用户表设计 SET FOREIGN_KEY_CHECKS=0; CREATE DATABASE sample; USE sample; ...
- 关于sublime使用中写less代码高亮显示问题
一开始在没有配置的情况下在sublime中写less代码是不会有高亮显示的.下面说一下配置过程 一.安装Less2Css模块 打开sublime,ctrl+shift+p,输入package cont ...
- Delphi 窗体的释放和判断窗体是否存在
常规释放和关闭: Form.Free - 释放Form占用的所有资源.Free后,Form指针不能再使用,除非对Form重新赋值. Form.Hide - 隐藏Form.可以调用f ...
- CSS——外观样式及应用
CSS注释 CSS规则是使用 /* 需要注释的内容 */ 进行注释的,即在需要注释的内容前使用 “/*” 标记开始注释,在内容的结尾使用 “*/”结束. 例如: p { font-size: 14p ...
- delphi 可以自定义边框的文本框TSkinNormalEdit思路(QQ2011风格)
需求: QQ我的资料中基本资料窗体中的文本框: 正常状态下,文本框只有一条看起来只有一个像素的边框,边框的颜色从上到下由深到浅的渐变,当鼠标定位到该文本框时,其边框会变粗,而且边框的颜色加亮显示 如下 ...