二叉树

【问题描述】

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

  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. [资料]ObjectARX 2020参考指南翻译中文版

    chm使用Google Chrome浏览器翻译,有些翻译不是很理想,因为2万5千多个html文件, 修正难度太大,所以只处理了一部分. 非常感谢 gzxl 辛苦肉眼修正一些翻译问题. 欢迎进入QQ群: ...

  2. springcloud 连接docker中运行的RabbitMQ消息中间件。

    参考:https://blog.51cto.com/zero01/2173288 主要是记录几个坑: 第一个坑:开始订单服务中配置文件是: #配置rabbitmq 2019.5.17 added by ...

  3. Git 工作流之 GitFlow

    GitFlow学习: 先学习这篇:点击打开链接 Gitflow工作流是经典模型,体现了工作流的经验和精髓.随着项目过程复杂化,会感受到这个工作流中深思熟虑和威力. ////////////////// ...

  4. WordPress 设计学习

    "One can never be defeated until defeat has been accepted as a reality"----- Bruce Lee 官网免 ...

  5. VueJS中学习使用Vuex详解

    转载自:https://segmentfault.com/a/1190000015782272,做了部分修改(这里建议不要用所谓的getters,一来多次一举,二来模块化时会产生很不协调的用法) 在S ...

  6. javassist标识符

    符号 含义 $0, $1, $2, ... this and 方法的参数 $args 方法参数数组.它的类型为 Object[] $$ 所有实参.例如, m($$) 等价于 m($1,$2,...) ...

  7. 【LeetCode】盛最多水的容器【双指针+贪心 寻找最大面积】

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...

  8. Eclipse Block Selection(块选择)快捷键 Alt + Shift + A

    说实话,我暂时还没用过这个快捷键.但是不代表以后我也不会用它. Eclipse 有个地方可以专门查看这些小技巧. Help → Tip of the Day 进入下面这个窗口: 将 Unread on ...

  9. [洛谷P5329][SNOI2019]字符串

    题目大意:给一个长度为$n$的字符串$s$,字符串$p_i$为字符串$s$去掉第$i$个字符后形成的字符串.请给所有字符串$p_i$排序(相同字符串按编号排序) 题解:先去掉所有连续相同字符,因为它们 ...

  10. idea 中激活 JRebel

    JRebel介绍: JRebel是一款JVM插件,它使得Java代码修改后不用重启系统,立即生效.IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,修改才能 ...