3043: IncDec Sequence

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 248  Solved: 139
[Submit][Status]

Description

给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一。
问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。

Input

第一行一个正整数n 
接下来n行,每行一个整数,第i+1行的整数表示ai。

Output

第一行输出最少操作次数
第二行输出最终能得到多少种结果

Sample Input

4
1
1
2
2

Sample Output

1
2

HINT

对于100%的数据,n=100000,0<=ai<2147483648

  正解传送门:http://blog.csdn.net/willinglive/article/details/38419573

  我看到这道题时并没有想到正解,但是很容易yy出来修改策略,每次填满最低的那一段区间,像涨水一样一直涨到顶端,离散处理将低于x的所有值提升到x的增加次数,然后倒着在做一遍,如果暴力做的话肯定会TLE,我们观察每次增加的区间数量即为低于x的区间联通块数量,这不是涨水求联通数的裸题?。。。。

  最后,因为我先离散化了所有点,所以如果我想回答询问2的话,需要回答离散之前的位置个数,这一点很容易wa。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 110000
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
typedef long long qword;
int a[MAXN];
pair<int,int> b[MAXN];
int c[MAXN];
int n,m;
qword v1[MAXN],v2[MAXN];
int uf[MAXN];
int get_fa(int now)
{
return uf[now]==now ? now : uf[now]=get_fa(uf[now]);
}
int comb(int x,int y)
{
x=get_fa(x);
y=get_fa(y);
if (x==y)return false;
uf[x]=y;
return true;
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&n);
int i,j,k;
for (i=;i<n;i++)
{
scanf("%d",a+i);
b[i].first=a[i];
b[i].second=i;
c[i]=a[i];
}
sort(c,c+n);
m=unique(c,c+n)-c;
sort(b,&b[n]);
int nowc=;
qword tot=;
int x,y;
for (i=;i<n;i++)uf[i]=i;
for (i=;i<n;i++)
{
x=b[i].second;
tot++;
if (x && a[x-]<=a[x])
tot-=comb(x-,x);
if (x<n- && a[x+]<a[x])
tot-=comb(x+,x);
if (i!=n- && b[i+].first!=b[i].first)
{
v1[nowc+]=v1[nowc]+tot*(c[nowc+]-c[nowc]);
nowc++;
}
}
nowc=m-;
tot=;
for (i=;i<n;i++)uf[i]=i;
for (i=n-;i>=;i--)
{
x=b[i].second;
tot++;
if (x<n- && a[x+]>=a[x])
tot-=comb(x+,x);
if (x && a[x-]>a[x])
tot-=comb(x-,x);
if (i && b[i-].first!=b[i].first)
{
v2[nowc-]=v2[nowc]+tot*(c[nowc]-c[nowc-]);
nowc--;
}
}
qword ans=INFL;
int mina=INF,maxa=-INF;
for (i=;i<m;i++)
{
if (v1[i]+v2[i]<ans)
{
ans=v1[i]+v2[i];
mina=INF,maxa=-INF;
}
if (v1[i]+v2[i]==ans)
mina=min(mina,c[i]),maxa=c[i];
}
printf("%lld\n%d\n",ans,maxa-mina+);
}

最新文章

  1. 查询SqlServer中每张表的记录数
  2. Android工作学习第5天之Activity的完全退出程序
  3. selenium隔离环境安装、以及示例
  4. Dell 服务器做Raid
  5. JDBC之java数据库的连接与简单的sql语句执行
  6. ACDream-C - Transformers&#39; Mission(Dijastra最短路径)
  7. Sizzle一步步实现所有功能(一)
  8. Amazon.com: NEW VI AND VIM EDITOR KEYBOARD STICKER: Office Products
  9. Linux驱动技术(四) _异步通知技术
  10. @Scope注解
  11. 背水一战 Windows 10 (110) - 通知(Tile): secondary tile 模板之基础, secondary tile 模板之文本
  12. webpack模块定义和使用的模式
  13. java多线程中最佳的实践方案是什么?
  14. sqlserver数据库系统性能监控步骤
  15. 关于Java源文件中public类的问题
  16. 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V1
  17. 看看大神们是怎么解决一些【bng】的哪!!!!
  18. 水晶报表填充.Net Objects数据源
  19. 【机器学习】粗糙集(Rough Set Approach)
  20. JAVA WEB开发中的资源国际化

热门文章

  1. 使用摘要流获取文件的MD5
  2. iOS 并行编程:GCD Dispatch Sources
  3. textarea限制字符数
  4. w3c 学习html DOM
  5. Linq常用查询运算符
  6. HTML 学习整理
  7. HttpServlet was not found on the Java
  8. 几种工具反编译被编译好的DLL文件
  9. asp.net中Get请求和Post请求
  10. Ext.Net学习笔记05:Ext.Net DirectEvents用法详解