[考试反思]1105csp-s模拟测试102: 贪婪


还是有点蠢。。。
多测没清空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: 贪婪的更多相关文章
- [考试反思]0718 NOIP模拟测试5
最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...
- [考试反思]0814NOIP模拟测试21
前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...
- [考试反思]1109csp-s模拟测试106:撞词
(撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...
- [考试反思]0909csp-s模拟测试41:反典
说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...
- [考试反思]0729NOIP模拟测试10
安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...
- [考试反思]0714/0716,NOIP模拟测试3/4
这几天时间比较紧啊(其实只是我效率有点低我在考虑要不要坐到后面去吹空调) 但是不管怎么说,考试反思还是要写的吧. 第三次考试反思没写总感觉缺了点什么,但是题都刷不完... 一进图论看他们刷题好快啊为什 ...
- [考试反思]1003csp-s模拟测试58:沉淀
稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...
- [考试反思]0816NOIP模拟测试23
210 210 210 170 还可以.暴力打满就rk4了? 但不管怎么说,总算是在改完题之后理直气壮的写考试反思了. T1是个dp,说水也不太水.(当然某脸只要A掉了一道题就要说那是水题) 我的思路 ...
- [考试反思]0801NOIP模拟测试11
8月开门红. 放假回来果然像是神志不清一样. 但还是要接受这个事实. 嗯,说好听点,并列rank#7. 说难听点,垃圾rank#18. 都不用粘人名就知道我是哪一个吧... 因为图片不能太长,所以就不 ...
随机推荐
- [JavaScript] 《JavaScript高级程序设计》笔记
1.|| 和 && 这两个逻辑运算符和c#是类似的,都是惰性的计算 a() || b() 若a()为真返回a()的结果,此时b()不计算: a()为假则返回b() a() &am ...
- Springboot + Mysql8实现读写分离
在实际的生产环境中,为了确保数据库的稳定性,我们一般会给数据库配置双机热备机制,这样在master数据库崩溃后,slave数据库可以立即切换成主数据库,通过主从复制的方式将数据从主库同步至从库,在业务 ...
- C# 读取控制台的Console.Write
一个程序去调用另一个xxx.exe的时候,需要记录下这个exe里面的console.write的输出 public static string InvokeExcute(string Command) ...
- Django中的表关系实现及操作
表关系的实现 预备知识 ORM的正向操作和反向操作: 1.正向操作:一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作. 2.反向操作:被外键所关联的模型,通过该模型对外键所在模型 ...
- BUUCTF刷题记录(Web方面)
WarmUp 首先查看源码,发现有source.php,跟进看看,发现了一堆代码 这个原本是phpmyadmin任意文件包含漏洞,这里面只不过是换汤不换药. 有兴趣的可以看一下之前我做的分析,http ...
- 第二篇 python进阶
目录 第二篇 python进阶 一 数字类型内置方法 二 字符串类型内置方法 三 列表类型内置方法(list) 四 元组类型内置方法(tuple) 五 字典内置方法 六 集合类型内置方法(self) ...
- 深入理解Netty框架
前言 本文讨论的主题是Netty框架,本着3W原则 (What 是什么?->Why 为什么?->How 如何做?)来一步步探究Netty原理和本质以及运用场景. 了解基本名词 1.BIO. ...
- 【DP合集】m-knapsack
给出 n 个物品,第 i 个物品有重量 w i .现在有 m 个背包,第 i 个背包的限重为 c i ,求最少用几个背 包能装下所有的物品. Input 输入的第一行两个整数 n, m ( n ≤ 2 ...
- Roadmap of FE
未完待补充......
- Python_箱型图绘制与特征值获取
它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比较 如何利用Python绘制箱型图 需要的import的包 import matplotlib.pyplot as plt from m ...