标签:
Time Limit: 20 Sec
Memory Limit: 256 MB
http://codeforces.com/problemset/problem/5/E
Input
The first line of the input data contains an integer number n (3 ≤ n ≤ 106), n — the amount of hills around the capital. The second line contains n numbers — heights of the hills in clockwise order. All height numbers are integer and lie between 1 and 109.
Output
Print the required amount of pairs.
Sample Input
5
1 2 4 5 3
Sample Output
7
题意
给你一个环的山,如果两个山之间没有比这座山更高的山的话,那么这两座山是可以互相看见的,然后问你最后有多少座山可以互相看见
题解:
首先我们把环变成一个链,然后用一个并查集的思想,处理每一座山左边第一个比这个山高的山是哪个,右边第一个比这个山高的是哪个,这个区域内和这个山高度一样的山有多少
然后跑一发并查集就好了
代码
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 1000010 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; //const int inf=0x7fffffff; const int inf=0x3f3f3f3f; /* inline void P(int x) { Num=0;if(!x){putchar(‘0‘);puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } */ inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline void P(int x) { Num=0;if(!x){putchar(‘0‘);puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } //************************************************************************************** int a[maxn]; int b[maxn]; int l[maxn]; int r[maxn]; int k[maxn]; int main() { int n=read(); int p=-1; for(int i=0;i<n;i++) { a[i]=read(); if(p==-1) p=i; else if(a[i]>a[p]) { p=i; } } for(int i=0;i<n;i++) b[i]=a[(i+p+n)%n]; b[n]=a[p]; for(int i=1;i<n;i++) { l[i]=i-1; while(l[i]>0&&b[i]>=b[l[i]]) l[i]=l[l[i]]; } k[n]=0; for(int i=n-1;i>=0;i--) { r[i]=i+1; while(r[i]<n&&b[i]>b[r[i]]) r[i]=r[r[i]]; if(r[i]<n&&b[i]==b[r[i]]) { k[i]=k[r[i]]+1; r[i]=r[r[i]]; } } ll ans=0; for(int i=1;i<n;i++) { ans+=k[i]; ans+=1; if(l[i]!=0||r[i]!=n) ans++; } cout<<ans<<endl; }
Codeforces Beta Round #5 E. Bindian Signalizing 并查集
标签:
原文地址:http://www.cnblogs.com/qscqesze/p/4595160.html