[51nod1482]部落信号 单调栈
题解:
可以发现这是一道单调栈的题目,首先来考虑数字没有重复时如何统计贡献。
因为这是一个环,而如果我们从最高的点把环断开,并把最高点放在链的最后面(顺时针移动),那么因为在最高点两侧的点无法互相看见,相当于就把环转化为链的问题了。
因此维护递减的单调栈,如果进来的点比栈顶高就弹出并统计1的贡献。
但是这样会有遗漏,我们观察什么情况下会遗漏。
因为是从1开始遍历,因此在前面的节点在遍历到n时完全有可能已经被弹走了,然而因为这是一个环,断开点(最高点)说不定还可以回头看见它。因此这种情况会被遗漏。
但如果又反着统计又会统计重复,因此考虑不统计最高点的贡献,然后最后再暴力跑2遍统计断开点的贡献。
但是数字可能有重复,怎么办?
重复数字会带来很多细节上的问题,比如8333中有5的贡献,而直接弹走显然统计不到5.又比如最大值可能有很多个,因此会将整个数列分为很多小段,,,等等诸如此类。
因此对于第一种情况,我们记录一下当前栈中每个数字有多少个,因为数字可能很大,但个数不多,因此一开始要离散化一下。
对于第二种情况,可以在最后暴力统计一下最高点两两搭配的方案数。
细节很多,注意调试&对拍
- #include<bits/stdc++.h>
- using namespace std;
- #define R register int
- #define AC 1001000
- #define LL long long
- int n, id, k, maxn, num, last, cnt;
- LL ans;
- int ss[AC], t[AC], tot[AC];
- int s[AC], top;
- bool vis[AC];
- inline int read()
- {
- int x = ;char c = getchar();
- while(c > '' || c < '') c = getchar();
- while(c >= '' && c <= '') x = x * + c - '', c = getchar();
- return x;
- }
- inline void upmax(int &a, int b)
- {
- if(b > a) a = b;
- }
- inline int get(int x)
- {
- if(x < ) x += n;
- return x > n ? x - n : x;
- }
- int half(int x)
- {
- int l = , r = cnt;
- while(l < r)
- {
- int mid = (l + r) >> ;
- if(ss[mid] == x) return mid;
- else if(ss[mid] < x) l = mid + ;
- else r = mid - ;
- }
- return l;
- }
- void pre()
- {
- n = read();
- for(R i = ; i <= n; i ++)
- {
- ss[i] = read();
- if(ss[i] > k) id = i, k = ss[i], num = ;
- else if(ss[i] == k) ++ num;
- }
- id = get(id + );
- for(R i = ; i <= n; i ++) t[i] = ss[get(id + i - )];
- sort(ss + , ss + n + );
- for(R i = ; i <= n; i ++)
- if(ss[i] != ss[i + ]) ss[++cnt] = ss[i];
- for(R i = ; i <= n; i ++) t[i] = half(t[i]);
- k = cnt;
- }
- /*8
- 3 1 5 7 1 1 7 8 */
- void work()
- {
- for(R i = ; i < n; i ++)//不统计中断处的
- {
- int tmp = (top && s[] != t[i]);
- // printf("%d\n", top);
- while(top && s[top] < t[i]) -- tot[s[top]], -- top, ++ ans;
- if(top && s[top] != t[i]) ++ ans;
- ++ tot[t[i]], s[++top] = t[i];
- if(tot[t[i]] - ) ans += tot[t[i]] - + tmp;
- // printf("%d\n", top);
- }
- for(R i = ; i <= n; i ++)
- {
- if(t[i] == k) break;
- if(vis[i]) continue;
- if(t[i] >= maxn && !vis[i]) ++ ans, vis[i] = true;
- upmax(maxn, t[i]);
- }
- maxn = ;
- for(R i = n - ; i; i --)
- {
- if(t[i] == k) break;
- if(t[i] >= maxn && !vis[i]) ++ ans, vis[i] = true;
- upmax(maxn, t[i]);
- }
- if(num > ) ans += num * (num - ) / - (num - ) * (num - ) / ;
- printf("%lld\n", ans);
- }
- int main()
- {
- // freopen("in.in", "r", stdin);
- pre();
- work();
- // fclose(stdin);
- return ;
- }
[51nod1482]部落信号 单调栈的更多相关文章
- BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 8748 Solved: 3835[Submi ...
- BZOJ 4453: cys就是要拿英魂![后缀数组 ST表 单调栈类似物]
4453: cys就是要拿英魂! Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 90 Solved: 46[Submit][Status][Discu ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- bzoj1510: [POI2006]Kra-The Disks(单调栈)
这道题可以O(n)解决,用二分还更慢一点 维护一个单调栈,模拟掉盘子的过程就行了 #include<stdio.h> #include<string.h> #include&l ...
- BZOJ1057[ZJOI2007]棋盘制作 [单调栈]
题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应八八六十四卦,黑白对应阴阳. 而我们的 ...
- 洛谷U4859matrix[单调栈]
题目描述 给一个元素均为正整数的矩阵,上升矩阵的定义为矩阵中每行.每列都是严格递增的. 求给定矩阵中上升子矩阵的数量. 输入输出格式 输入格式: 第一行两个正整数n.m,表示矩阵的行数.列数. 接下来 ...
- POJ3250[USACO2006Nov]Bad Hair Day[单调栈]
Bad Hair Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17774 Accepted: 6000 Des ...
- CodeForces 548D 单调栈
Mike and Feet Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Subm ...
随机推荐
- zookeeper环境搭建(Linux)
安装zookeeper 安装jdk(此处省略) 解压tar包并配置变量环境 配置文件修改 将/usr/local/src/zookeeper-3.4.5/conf这个路径下的zoo_sample.cf ...
- (数据科学学习手札18)二次判别分析的原理简介&Python与R实现
上一篇我们介绍了Fisher线性判别分析的原理及实现,而在判别分析中还有一个很重要的分支叫做二次判别,本文就对二次判别进行介绍: 二次判别属于距离判别法中的内容,以两总体距离判别法为例,对总体G1,, ...
- Spring配置文件一直报错的根源所在
跳坑后的感悟总结 Spring在配置文件中经常会报XML错误,以下是几种常见的解决办法 方式一:打开eclipse-->Project-->Clean ;清除一下 方式二:查看xml配置文 ...
- Mysql双主操作
MySQL双主(主主)架构方案 在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果 ...
- spring 读取properties文件--通过注解方式
问题: 需要通过properties读取页面的所需楼盘的名称.为了以后便于修改. 解决: 可以通过spring的 PropertiesFactoryBean 读取properties属性,就不需要自己 ...
- Qt irrlicht(鬼火)3D引擎 摄像机旋转问题
点击打开链接Irrlicht中的摄像有一个函数 setUpVector() if (m_device != 0 ) { core::vector3df rotation(y,x,0.f); m_cam ...
- session、token、cookie的区别
token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件cookie就是写在客户端的一个txt文件,里面包括你登录信息之类的,这样你下次在登录某个网站,就会自动调用co ...
- 8.0 TochAction各种用法
1.滑动---TouchAction 支持相对坐标.绝对坐标.Element 注意看顶部的导入TouchAction这个库.. #实例化 action = TouchAction(driver) # ...
- zabbix 一些问题随记
1. zabbix运行不了,显示被锁,去检查日志中的报错 2. 配置界面,连接不到数据库,检查server配置文件,mysql授权命令要准确,重启 3. 显示没有php文件,下载即可,或者修改网页访问 ...
- python 基础篇 15 内置函数和匿名函数
------------------------>>>>>>>>>>>>>>>内置函数<<< ...