二叉树

【问题描述】

从前有一棵二叉树,我们用如下方式来表示这棵二叉树。

  1. 如果一个节点没有儿子,我们用“0”来表示他。
  2. 如果一个节点有一个儿子,我们对它的表示以“1”开头,后面接对它儿子的表示。
  3. 如果一个节点有两个儿子,我们对它的表示以“2”开头,后面先接对它左儿子的表示,后接对它右儿子的表示。

KJDH 十分贪玩,将这棵树染了色,KJDH 又十分聪明,它染色又很有规则:每个节点不能和它的孩子有相同的颜色,如果一个节点有两个孩子,那么这两个孩子也不能有相同的颜色。 由于这个树年代久远了,所以我们看不清每个节点的颜色了,但我们知道KJDH 只染了红黄白三种颜色。我们想知道这棵树最多和最少有多少个节点是白色的。

【输入格式】

输入文件名为 tree.in。 输入文件只有一行,一个字符串,只有“0”,“1”,“2”组成,表示这 棵树的结构。

【输出格式】

输出文件名为 tree.out。 输出文件包含两个用空格隔开的数,分别表示白色节点的最多和最少数量。

【输入输出样例 1】

tree.in

200

tree.out

1 1

【输入输出样例 2】

tree.in

1122002010

tree.out

5 2

【数据规模与约定】

对于 20% 的数据,len<=10。

对于 50% 的数据,len<=2000

对于 100% 的数据,len<=500000。其中 len 为读入字符串的长度。

题解

我还想了好一会儿怎么建树。用栈模拟括号序列即可。

然后就是睿智树形DP。

co int N=500000+10;
char str[N];
struct node{int id,val;};
int len,lc[N],rc[N],n;
int main(){
freopen("tree.in","r",stdin),freopen("tree.out","w",stdout);
scanf("%s",str+1),len=strlen(str+1);
stack<node> st;
for(int i=1;i<=len;++i){
st.push((node){++n,str[i]-'0'});
while(st.top().val==0){
int x=st.top().id;st.pop();
if(x==1) break;
int fa=st.top().id;
// cerr<<"link "<<fa<<" "<<x<<endl;
lc[fa]?rc[fa]=x:lc[fa]=x;
--st.top().val;
}
}
dfs(1);
printf("%d %d\n",max(f[1][0],max(f[1][1],f[1][2])),min(g[1][0],min(g[1][1],g[1][2])));
return 0;
}

跳舞

【问题描述】

KJDH 有 n 个妹子,从 1 到 n 依次编号,每个妹子都会跳舞,第 i 个妹子跳舞的魅力值为 ai,有一天 KJDH 在 IOI 赛场上捧了杯,他的 n 个妹子想要庆祝一下,要为他跳舞,总共要跳 n*(n+1)/2 支舞,分别由编号为 i~j 的妹子跳舞(1<=i<=j<=n)。

每跳一支舞 KJDH 都会非常高兴从而增加愉悦值,编号为 i~j 的妹子跳舞能增加的愉悦值为

(j-i+1)Min(ai,ai+1,…,aj)Max(ai,ai+1,…,aj)

问 KJDH 在跳完 n*(n+1)/2 支舞后,能增加多少愉悦值,答案对 1000000007 取模。

【输入格式】

输入文件名为 dance.in。

输入共 2 行。

第 1 行包含 1 个正整数 n ,表示 n 个妹子。

第 2 行包含 n 个用空格隔开的正整数 a1,a2,…,an。表示每个妹子跳舞的魅力值。

【输出格式】

输出文件名为 dance.out。

输出共 1 行,包含 1 个整数,表示 KJDH 能增加的愉悦值。

【输入输出样例 1】

dance.in

4

2 4 1 4

dance.out

109

【输入输出样例 1 说明】

总共跳了 6 支舞。用(i,j)表示编号 i~j 的妹子跳舞增加的愉悦值。

(1,1)=4 (1,2)=16 (1,3)=12 (1,4)=16

(2,2)=16 (2,3)=8 (2,4)=12

(3,3)=1 (3,4)=8

(4,4)=16

全部加起来为 109。

【数据规模与约定】

对于 60%的数据,n<=2000;

对于 100%的数据,n<=500000,1<=ai<=108

ChiTongZ的题解

把\(j-i+1\)从答案中拆出去

\[\sum_{j=1}^n\sum_{i=1}^j(j-i+1) \max(i,j) \min(i,j)\\
=\sum_{j=1}^n j \sum_{i=1}^j \max(i,j) \min(i,j) - \sum_{i=1}^n (i-1) \sum_{j=i}^n \max(i,j) \min(i,j)
\]

第二重求和符号可以用单调栈+线段树维护。

用单调栈来得知区间覆盖情况,用线段树维护区间覆盖标记,区间min、max和,区间min*max和。发现就可以做了。

时间复杂度\(O(n \log n)\),出题人卡常数。

#include<bits/stdc++.h>
#define co const
#define il inline
template<class T> T read(){
T x=0,w=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*w;
}
template<class T> T read(T&x){
return x=read<T>();
}
using namespace std;
typedef long long LL; co int mod=1000000000+7;
il int add(int a,int b){
return (a+=b)>=mod?a-mod:a;
}
il int mul(int a,int b){
return (LL)a*b%mod;
} co int N=500000+10;
namespace T{
int l[N<<2],r[N<<2];
int tag[N<<2][2],sum[N<<2][2];
int pro[N<<2];
#define lc (x<<1)
#define rc (x<<1|1)
void build(int x,int l,int r){
T::l[x]=l,T::r[x]=r;
tag[x][0]=tag[x][1]=sum[x][0]=sum[x][1]=0;
pro[x]=0;
if(l==r) return;
int mid=(l+r)>>1;
build(lc,l,mid),build(rc,mid+1,r);
}
void set(int x,int k,int v){
tag[x][k]=v,sum[x][k]=mul(r[x]-l[x]+1,v);
pro[x]=mul(sum[x][k^1],v);
}
void push_down(int x){
for(int k=0;k<2;++k)if(tag[x][k]){
set(lc,k,tag[x][k]),set(rc,k,tag[x][k]);
tag[x][k]=0;
}
}
void push_up(int x){
for(int k=0;k<2;++k)
sum[x][k]=add(sum[lc][k],sum[rc][k]);
pro[x]=add(pro[lc],pro[rc]);
}
void change(int x,int ql,int qr,int k,int v){
if(ql<=l[x]&&r[x]<=qr)
return set(x,k,v);
push_down(x);
int mid=(l[x]+r[x])>>1;
if(ql<=mid) change(lc,ql,qr,k,v);
if(qr>mid) change(rc,ql,qr,k,v);
push_up(x);
}
int query(int x,int ql,int qr){
if(ql<=l[x]&&r[x]<=qr)
return pro[x];
push_down(x);
int mid=(l[x]+r[x])>>1;
if(qr<=mid) return query(lc,ql,qr);
if(ql>mid) return query(rc,ql,qr);
return add(query(lc,ql,qr),query(rc,ql,qr));
}
}
int n,a[N];
int s1[N],t1,s2[N],t2; // max,min int main(){
freopen("dance.in","r",stdin),freopen("dance.out","w",stdout);
read(n);
for(int i=1;i<=n;++i) read(a[i]);
int ans=0;
T::build(1,1,n);
for(int i=1;i<=n;++i){
while(t1&&a[s1[t1]]<=a[i]) --t1;
T::change(1,t1?s1[t1]+1:1,i,1,a[i]);
s1[++t1]=i;
while(t2&&a[s2[t2]]>=a[i]) --t2;
T::change(1,t2?s2[t2]+1:1,i,0,a[i]);
s2[++t2]=i;
ans=add(ans,mul(i,T::query(1,1,i)));
}
T::build(1,1,n),t1=t2=0;
for(int i=n;i>=1;--i){
while(t1&&a[s1[t1]]<=a[i]) --t1;
T::change(1,i,t1?s1[t1]-1:n,1,a[i]);
s1[++t1]=i;
while(t2&&a[s2[t2]]>=a[i]) --t2;
T::change(1,i,t2?s2[t2]-1:n,0,a[i]);
s2[++t2]=i;
ans=add(ans,mod-mul(i-1,T::query(1,i,n)));
}
printf("%d\n",ans);
return 0;
}

数列

【问题描述】

我们定义 n-数列是具有如下性质的数列。

  1. 数列的长度不小于 3,且数列中的每个元素都是 1 到 n 之间的整数。
  2. 若数列为 a1,a2,……,am,则对于任意 3<=k<=m,都满足

    (ak-ak-2)(ak-1-ak-2)<0

现在给你 n,求 n-数列的个数。答案对 1000000007 取模。

【输入格式】

输入文件名为 seq.in。

输入共一行,为 n。

【输出格式】

输出文件名为 seq.out。 输出一行,表示 n-数列的个数

【输入输出样例 1】

seq.in

3

seq.out

2

【输入输出样例 1 说明】

两个 n-序列分别是(2,1,3)和(2,3,1)

【输入输出样例 2】

seq.in

666

seq.out

805846404

【数据规模与约定】

对于10%的数据,n<=10

对于30%的数据,n<=200

对于50%的数据,n<=2000

对于70%的数据,n<=1018

对于100%的数据,3<=n<=105000

还是ChiTongZ的题解

注意到若设\(b_i=a_{i+1}-a_i\),则\(|b_i|\)是单调递增的,并且\(b_i\)正负交替。

考虑\(a_i - i\)的图像,把它连成折线图,那么我们要做的就是确定\(a_i\)的波动范围,即\(\max \{ |b_i| \}=|b_m|\),然后求出这个波动范围的方案数,乘上这个范围摆放位置的方案数。

考虑枚举\(|b_m|\),先假设\(b_m\)为正数,最后方案数乘以\(2\)即可。

\[\frac 12 ans=\sum_{i=1}^{n-1} 2^{i-1} (n-1-i+1)
\]

因为\(b\)的严格的性质,所以\(1 \sim i-1\)的任何一种出现方式都唯一对应一种方案。

但是这里没有保证\(|\{a_n\}| \ge 3\),即\(|\{b_n\}| \ge 2\),所以要减去\(| \{ b_n \}| = 1\)情况。

\[\frac 12 ans=\sum_{i=1}^{n-1} 2^{i-1} (n-1-i+1) - \sum_{i=1}^{n-1} (n-1-i+1)
\]

然后通过现有的套路进行计算,得出答案

\[ans=2^{n+1}-n^2-n-2
\]

时间复杂度\(O(\lg n)\)。

#include<bits/stdc++.h>
#define co const
#define il inline
template<class T> T read(){
T x=0,w=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-') w=-w;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*w;
}
template<class T> T read(T&x){
return x=read<T>();
}
using namespace std;
typedef long long LL; co int mod=1000000000+7;
il int fpow(int a,int b){
int ans=1;
for(;b;b>>=1,a=(LL)a*a%mod)
if(b&1) ans=(LL)ans*a%mod;
return ans;
} int main(){
freopen("seq.in","r",stdin),freopen("seq.out","w",stdout);
int m=0,n=0;
for(char c=getchar();isdigit(c);c=getchar()){
m=((LL)m*10+c-'0')%(mod-1);
n=((LL)n*10+c-'0')%mod;
}
int ans=fpow(2,m+1)+mod-((LL)n*n+n+2)%mod;
printf("%d\n",ans%mod);
return 0;
}

test20190814 NOIP2019 模拟题的更多相关文章

  1. test20190815 NOIP2019 模拟题

    100+60+40=200,被后面两个题卡着我很不爽. 立方数 [问题描述] 作为 XX 战队的狂热粉丝,MdZzZZ 看到了自己心仪的队伍在半决赛落败,顿时 心灰意冷.看着自己手中的从黄牛那里抢来的 ...

  2. poj 1008:Maya Calendar(模拟题,玛雅日历转换)

    Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 D ...

  3. poj 1888 Crossword Answers 模拟题

    Crossword Answers Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 869   Accepted: 405 D ...

  4. CodeForces - 427B (模拟题)

    Prison Transfer Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  5. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

  6. 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中

    题目名称 正确答案  序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer. ...

  7. UVALive 4222 Dance 模拟题

    Dance 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&pag ...

  8. cdoj 25 点球大战(penalty) 模拟题

    点球大战(penalty) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/2 ...

  9. Educational Codeforces Round 2 A. Extract Numbers 模拟题

    A. Extract Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/pr ...

随机推荐

  1. ENSP静态链路聚合实验配置要点及实例

    链路聚合分为:静态链路聚合.动态链路聚合链路聚合的负载分担模式:对于二层数据流,系统会根据MAC地址(源mac地址和目的mac地址来计算),而对于三层数据流则会根据ip地址来进行负载分担计算. 静态链 ...

  2. rest_framework框架——版本控制组件

    API版本控制可以用来在不同的客户端使用不同的行为.REST框架提供了大量不同的版本设计. 版本控制是由传入的客户端请求决定的,并且可基于请求URL,或者基于请求头. rest_framework 当 ...

  3. 使用Python快速实现简单的人脸检测

    最近有个比较要好的朋友问我能不能从监控视频里识别到从监控跟前经过的指定的人.因为他们单位的监控室经常要花大量的人力跟时间去找某个人在哪个位置出现过的证据.听起来像是一份比较有挑战性的任务,就答应他试试 ...

  4. pymysql 模块简单使用

    目录 pymysql 模块简单使用 安装 pymysql 模块 使用 pymysql 连接数据库 并插入数据 使用pymysql 插入数据 修改查询显示结果 pymysql 模块简单使用 安装 pym ...

  5. Asp.Net Core异常处理

    本文将介绍在ASP.Net Core中处理异常的几种方法 1使用开发人员异常页面(The developer exception page) 2配置HTTP错误代码页 Configuring stat ...

  6. SQL——AND、OR运算符

    一.AND.OR运算符基本说明 AND : 所有条件成立,则筛选出这条记录. OR : 只要其中一个条件成立,则筛选出这条记录. 演示student表: 二.AND运算符使用 查询name = '小明 ...

  7. Android--卸载应用

    获取应用列表: List<PackageInfo> packages = getPackageManager().getInstalledPackages(0); for (Package ...

  8. UOJ348 WC2018 州区划分 状压DP、欧拉回路、子集卷积

    传送门 应该都会判欧拉回路吧(雾 考虑状压DP:设\(W_i\)表示集合\(i\)的点的权值和,\(route_i\)表示点集\(i\)的导出子图中是否存在欧拉回路,\(f_i\)表示前若干个城市包含 ...

  9. JavaTCP粘包、拆包

    import java.nio.ByteBuffer; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBu ...

  10. ASP.NET Core在支付宝小程序中使用signalR

    Github有一个经过重写的微信小程序SignalR的js类库 https://github.com/liangshiw/SignalRMiniProgram-Client 于是我把他改成支付宝小程序 ...