还是有点蠢。。。

多测没清空T3挂40。。。(只得了人口普查分20)

多测题要把样例复制粘两遍自测一下防止未清空出锅。

然而不算分。。。

其实到现在了算不算也不重要了吧。。。

而且其实T3只考虑最长路上的点这个思路其实肯定都能想到啊。

懒得打。那么就分少啊。

对于分数,还是要贪婪一些的。

T1:你相信引力吗

维护最大值关系:肉眼可见的单调栈/队列。(刚开始认为是栈,后来其实发现是一个队列)

环,经典套路,拆成两倍长的序列。

维护一个单调不增的单调栈,根据题目含义画画图,可以发现答案是:

对于当前点,从栈里第一个严格大于当前元素的值开始数,栈里有多少个元素。

暴力思路就是二分。

可以发现你找到的那个元素后面的部分都会被弹掉,所以一边弹一边计数即可。

特殊的一点是权值相同的,这部分不会被弹栈,但是对答案也有贡献。

所以在每个元素入栈的时候记录一下栈顶有几个连续相同的元素即可。

然后还要考虑找到第一个比当前元素大的元素,所以检查一下栈底的元素是否比当前元素大,如果大的话再累加1个答案。

然后还要考虑环拉成序列以后同一个位置的元素可能在栈里出现2次。

所以就不是栈了,是个队列。如果队首元素的下表就是当前的下标,那么就弹出。

弹出的时候要考虑它对“栈里连续相同元素数量”的影响。

还有一个问题,如果对于一对冰锥,它的优弧和劣弧都满足条件,那么它的答案会被计算两次。

如果最大值出现了k次,那么它对答案产生的多出的贡献就是$\frac{k(k-1)}{2}$

特别的,当k=1时,如果次大值出现了j次,那么多出的答案就是$j$

所以把多出的贡献减去就是最终答案。

细节较多。但是如果上述分类讨论都注意到了的话调试还是挺简单的。

 #include<cstdio>
int read(){
register int p=;register char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')p=(p<<)+(p<<)+ch-,ch=getchar();
return p;
}
int n,a[],q[],p[],s[],h=,t,mx,se,tmx,tse;long long ans;
int main(){
freopen("jolyne.in","r",stdin);freopen("jolyne.out","w",stdout);
n=read();
for(int i=;i<=n;++i)a[i]=read();
for(int i=;i<=n;++i)
if(a[i]>mx)se=mx,tse=tmx,mx=a[i],tmx=;
else if(a[i]==mx)tmx++;
else if(a[i]>se)se=a[i],tse=;
else if(a[i]==se)tse++;
for(int i=;i<=n;++i){
while(t>=h&&a[i]>q[t])t--;
if(t>=h&&q[t]==a[i])s[++t]=s[t-]+;else s[++t]=;
q[t]=a[i];p[t]=i;
}
for(int i=;i<=n;++i){int nt=;
while(t>=h&&p[h]<=i)nt=a[i]==q[h],h++;
while(t>=h&&a[i]>q[t])t--,ans++;
if(t>=h&&q[t]==a[i])s[++t]=s[t-]+;else s[++t]=;
q[t]=a[i];p[t]=n+i;
if(h==t||q[h]!=q[t])nt=;
s[t]-=nt;ans+=s[t]-;if(q[h]!=a[i])ans++;
// for(int j=h;j<=t;++j)printf("%3d ",q[j]);puts("");
// for(int j=h;j<=t;++j)printf("%3d ",s[j]);puts("");
// printf("%lld\n",ans);
}
if(tmx==)ans-=tse;
else ans-=tmx*(tmx-1ll)/;
printf("%lld\n",ans);
}

T2:停不下来的团长奥尔加

比较明显的线性递推。

可以根据每个点的出度/入度平衡来做。

出度分为去右边的和去左边的,入度也是。

然后就可以递推了。

 #include<cstdio>
#define mod 1000000007
int n,to[];long long ans,oR[],oL[],iL[],iR[];
int main(){
freopen("rideon.in","r",stdin);
freopen("rideon.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;++i)scanf("%d",&to[i]);
iL[n+]=;
for(int i=n;i;--i){
oR[i]=iL[i+];
oL[i]=oR[i];
iR[to[i]]=(iR[to[i]]+oL[i])%mod;
iL[i]=(oR[i]+oL[i]-iR[i]+mod)%mod;
ans=(ans+iL[i]+iR[i])%mod;
}printf("%lld\n",ans);
}

T3:Lesson5!

这题为什么要多测啊啊啊?一定要记得清空不然调到死。

建超级源汇会好做一些。(不建也可以,区别不大)

先预处理出来源点到每个点的距离f,以及每个点到汇点的距离g。

正反拓扑得到。

然后对于每一条边,经过它的最长路是fx+gy+1。称之为边的权值。

对于删除一个点,那么所有与它有关的边都不能贡献答案。

所以再一个正向拓扑,分层考虑所有点。

对于每一个点,删除所有入边的权值的贡献(就是从数据结构里删除),此时出边的贡献还没有统计。

所谓的贡献答案,其实就是在所有可行的最长路中取出最大的那一个,是一个维护了多个最长路决策的数据结构。

(所以说题解说的好像多么玄乎一样)

先不考虑这个数据结构是什么,假设我们能应付它需要的所有操作。

所以其实当前的状态下,就相当与删除了这个点时的状态,所以此时的最长路就是删掉这个点的最长路。(就是从数据结构里找到最大值)

这个点考虑完之后就可以把它的出边都贡献答案了。(就是放入数据结构)

因为你会在进入这一层的时候删除,走出这一层的时候加入,那么其实它只会在本层到下一层的时间存在。

进入下一层的时候代表这条最长路的边就不再是这一条了而是在这条最长路上的下一条。所以一定会不重不漏的最优决策。

怎么求出答案?需要一个可以求最大值,可以删除的数据结构。

multiset。(于是我开始嘲笑出题人不会STL还要写权值线段树)

然后我被卡常了。。。

但是我坚决不打数据结构!所以就上priority_queue乱搞。

加一个懒惰删除即可。

不建立超级源汇的话,根据含义考虑,其实少的边就是从每一个点到其汇点的贡献,所以在拓扑开始之前直接把每个点到它的汇点的答案放进数据结构里就好了。

还有我感觉mikufun的思路很好,附个链接(虽然skyh没脸又爆跳父亲AC了然后才开始长脸重新改了一遍(再长脸脸该多大了啊。。。))

 #include<bits/stdc++.h>
using namespace std;
priority_queue<int>Q;
vector<int>v[];
int n,m,dp[],ans,ansp,cnt,fir[],l[],to[],deg[];
int f[],g[],q[],X[],Y[],delcnt[];
void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;deg[b]++;}
int main(){
freopen("johnny.in","r",stdin);
freopen("johnny.out","w",stdout);
int T;scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=;i<=n+;++i)fir[i]=f[i]=g[i]=,v[i].clear();
while(!Q.empty())Q.pop();
ans=;cnt=;
for(int i=;i<=m;++i)scanf("%d%d",&X[i],&Y[i]),link(X[i],Y[i]);
for(int i=m+;i<=m+n;++i)X[i]=,Y[i]=i-m,link(X[i],Y[i]);
m+=n;
for(int i=m+;i<=m+n;++i)X[i]=i-m,Y[i]=n+,link(X[i],Y[i]);
m+=n;n++;
int t=;
for(int i=;i<=n;++i)if(!deg[i])q[++t]=i;
for(int h=;h<=t;++h){
int p=q[h];
for(int i=fir[p];i;i=l[i]){
deg[to[i]]--;f[to[i]]=max(f[to[i]],f[p]+);
if(!deg[to[i]])q[++t]=to[i];
}
}
t=;for(int i=;i<=n;++i)fir[i]=;cnt=;
for(int i=;i<=m;++i)link(Y[i],X[i]);
for(int i=;i<=n;++i)if(!deg[i])q[++t]=i;
for(int h=;h<=t;++h){
int p=q[h];
for(int i=fir[p];i;i=l[i]){
deg[to[i]]--;g[to[i]]=max(g[to[i]],g[p]+);
if(!deg[to[i]])q[++t]=to[i];
}
}
t=;for(int i=;i<=n;++i)fir[i]=;cnt=;
for(int i=;i<=m;++i)link(X[i],Y[i]),v[Y[i]].push_back(+g[Y[i]]+f[X[i]]);
for(int i=;i<=n;++i)if(!deg[i])q[++t]=i;
Q.push();
for(int h=;h<=t;++h){
int p=q[h];
for(int i=;i<v[p].size();++i)delcnt[v[p][i]]++;
while(delcnt[Q.top()])delcnt[Q.top()]--,Q.pop();
if(Q.top()<ans&&p&&p!=n)ans=Q.top(),ansp=p;
if(Q.top()==ans&&p<ansp&&p)ansp=p;
for(int i=fir[p];i;i=l[i]){
deg[to[i]]--;Q.push(+f[p]+g[to[i]]);
if(!deg[to[i]])q[++t]=to[i];
}
}
printf("%d %d\n",ansp,ans-);
}
}

60M的读入量没写快读居然也过了。。。

[考试反思]1105csp-s模拟测试102: 贪婪的更多相关文章

  1. [考试反思]0718 NOIP模拟测试5

    最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...

  2. [考试反思]0814NOIP模拟测试21

    前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...

  3. [考试反思]1109csp-s模拟测试106:撞词

    (撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...

  4. [考试反思]0909csp-s模拟测试41:反典

    说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...

  5. [考试反思]0729NOIP模拟测试10

    安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...

  6. [考试反思]0714/0716,NOIP模拟测试3/4

    这几天时间比较紧啊(其实只是我效率有点低我在考虑要不要坐到后面去吹空调) 但是不管怎么说,考试反思还是要写的吧. 第三次考试反思没写总感觉缺了点什么,但是题都刷不完... 一进图论看他们刷题好快啊为什 ...

  7. [考试反思]1003csp-s模拟测试58:沉淀

    稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...

  8. [考试反思]0816NOIP模拟测试23

    210 210 210 170 还可以.暴力打满就rk4了? 但不管怎么说,总算是在改完题之后理直气壮的写考试反思了. T1是个dp,说水也不太水.(当然某脸只要A掉了一道题就要说那是水题) 我的思路 ...

  9. [考试反思]0801NOIP模拟测试11

    8月开门红. 放假回来果然像是神志不清一样. 但还是要接受这个事实. 嗯,说好听点,并列rank#7. 说难听点,垃圾rank#18. 都不用粘人名就知道我是哪一个吧... 因为图片不能太长,所以就不 ...

随机推荐

  1. Weex项目快速打包

    安装最新稳定版的Node.js 运行 cnpm install -g weex-toolkit 安装Weex 官方提供的 weex-toolkit 脚手架工具到全局环境中 运行 weex create ...

  2. Flume 学习笔记之 Flume NG高可用集群搭建

    Flume NG高可用集群搭建: 架构总图: 架构分配: 角色 Host 端口 agent1 hadoop3 52020 collector1 hadoop1 52020 collector2 had ...

  3. Dubbo学习系列之十五(Seata分布式事务方案TCC模式)

    上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...

  4. 关于Qt画点及计算机专业基础课程介绍

    在计算机图形图像学中,开始都是先画点,我曾经在汇编上tc2.0上画点,后来是MFC,VB,Qt,Python,我觉得对于计算机专业的选择QT的原因是它是个C系的功能强大庞大的库,可以少写很多代码,但是 ...

  5. 2019滴滴php面试总结 (包含面试题解析)

    2019滴滴java面试总结  (包含面试题) 本人6年开发经验.今年年初找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.滴滴等公司offer,岗位是既有php也有Java后端开发,最终选择去了滴滴 ...

  6. VPGAME 的 Kubernetes 迁移实践

    作者 | 伍冲斌  VPGAME 运维开发工程师 导读:VPGAME 是集赛事运营.媒体资讯.大数据分析.玩家社群.游戏周边等为一体的综合电竞服务平台.总部位于中国杭州,在上海和美国西雅图分别设立了电 ...

  7. HMLT clear 属性

    原文 : http://www.zhangxinxu.com/wordpress/2014/06/understand-css-clear-left-right-and-use/ clear 的四个值 ...

  8. My Idea About ID wly_sh (关于用户名 wly_sh 的猜想)

    I Wanna Say Is That- There's a guy called wsh in our computer room. That guy registered a blog in CS ...

  9. java集合之linkedList链表基础

    LinkedList链表: List接口的链接列表实现.允许存储所有元素(包含null).使用频繁增删元素. linkedList方法: void addFirst(E e) 指定元素插入列表的开头 ...

  10. 2,手动创建CAD二次开发项目--AutoCAD二次开发(2020版)

    本项目使用手动创建,意为不使用SDK模板. 从Visual Studio的“文件”下拉菜单中,选择“新建”->“项目...”. 在出现的“新建项目”对话框的“项目类型:”树中,单击“ Visua ...