2016百度之星 初赛2B ACEF

做了1001 1003 1005 1006

看题:http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=702

交题:http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0%D9%B6%C8%D6%AE%D0%C7%22+-+%B3%F5%C8%FC%A3%A8Astar+Round2B%A3%A9&source=1&searchmode=source

 

1001 区间的价值

乱搞?

做法简介:有多种做法,主要思想都是先算a[i]作为最小值能管辖的最大左右范围l[i], r[i],然后求[ l[i], r[i] ]区间内的最大值ma,判断是否可以更新ans[r[i] - l[i] + 1] = ma*a[i],能更新的话也可以更新更小的区间。

思路过程:

枚举所有区间?n^2,不行。

答案肯定是这样:大区间的结果小,小区间的结果大,单调的。那么如果算出了大区间的答案,可以更新到小区间。

发现很多区间的最小值是同一个,如果我们枚举最小值的话,可以求这个最小值管辖的最大左右范围。

求出了这个范围的话,我们再求一下这个区间的最大值,就能更新一下这个区间大小的答案,还可以更新小区间大小的答案。

这样能否得到所有区间大小的最优答案呢?

当然啦,因为我们固定了最小值,这个最小值能对应的最大的最大值被我们找到了,这就是这个最小值的最优答案。我们枚举最小值,就枚举了所有最优答案。

剩下的问题就是2个:

1.怎么确定某个最小值的管辖左右范围;

2.求某个区间的最大值

解:

1.两种方法:

(1)用DP,从做到右求l[i],从右到左求r[i],求好的值可以拿来用。(我没用这个方法

(2)用单调栈,二分找到比a[i]左边的比a[i]小的最右边的a[j],l[i] = j+1,具体见我的代码。

2.两种方法:

(1)RMQ-ST(我没用这个

(2)还是用单调栈,要先对区间[Li,Ri]排序,让Li有序。例如从小到大排,我们从右往左扫,把[Li, n-1]的元素都加入递减单调栈,二分找下标小于等于Ri的最大的数。具体见我的代码。好像有点复杂,还是学一个RMQ-ST比较好。

代码(闲着没事写了个类看看是不是能看得比较清晰,就写成这样了,感觉也不是很清晰。还学了一波函数指针):

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 24 #define WN(x) printf("%d\n",x);
 25 #define RE  freopen("D.in","r",stdin)
 26 #define WE  freopen("huzhi.txt","w",stdout)
 27 #define MP make_pair
 28 #define PB push_back
 29 #define PF push_front
 30 #define PPF pop_front
 31 #define PPB pop_back
 32 #define lowbit(x) ((x)&(-x))
 33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 34     if(ed>=st)cout<<a[st];
 35     int i;
 36     FOR(i,st+1,ed)cout<<' '<<a[i];
 37     puts("");
 38 }
 39 typedef long long LL;
 40 typedef unsigned long long ULL;
 41 typedef pair<int,int> PII;
 42 const double PI=acos(-1.0);
 43 const double EPS=1e-10;
 44 inline int sgn(double &x) {
 45     if(fabs(x) < EPS)return 0;
 46     if(x < 0)return -1;
 47     else return 1;
 48 }
 49 const int INF=0x3f3f3f3f;
 50 const int NINF=0x80000001;
 51 const int MAXN=111111;
 52 const int MAXM=33;
 53 const int MOD = 1000000007;
 54 
 55 bool littleThan(int x, int y) {
 56     return x<y;
 57 }
 58 bool biggerThan(int x, int y) {
 59     return x>y;
 60 }
 61 
 62 class MonoVector {
 63     bool (*cmp)(int,int);
 64     MonoVector() {}
 65 public:
 66     vector<PII> q;
 67     MonoVector(bool isDecrease) {
 68         if(isDecrease) cmp = biggerThan;
 69         else cmp = littleThan;
 70         q.clear();
 71     }
 72     void insert(int id, int value) {
 73         while(!q.empty() && cmp(value, q.back().second))
 74             q.pop_back();
 75         q.push_back(MP(id,value));
 76     }
 77     ///from right find to left, find the first one witch little/bigger than "value".
 78     int LeftStrangeId(int value) {
 79         int l = 0,r = q.size()-1;
 80         while(l<=r){
 81             int mid = (r-l)/2 + l;
 82             if(!cmp(q[mid].second , value)) r = mid - 1;
 83             else l = mid + 1;
 84         }
 85         if(l-1>=0) return q[l-1].first;
 86         else return -1;
 87     }
 88     int getLeftestValueWithIdNoBiggerThan(int id){
 89         int l = 0,r = q.size()-1;
 90         while(l<=r){
 91             int mid = (r-l)/2 + l;
 92             if(q[mid].first <= id) r = mid - 1;
 93             else l = mid + 1;
 94         }
 95         return q[l].second;
 96     }
 97     int size() {
 98         return q.size();
 99     }
100     void clear(){
101         q.clear();
102     }
103 };
104 
105 int n;
106 int a[MAXN];
107 LL ans[MAXN];
108 
109 void updateAns(int range, LL value){
110     if(value > ans[range]){
111         ans[range] = value;
112         if(range>1)updateAns(range - 1, value);
113     }
114 }
115 
116 PII lr[MAXN];
117 bool qcmp(int x,int y){
118     return lr[x].first < lr[y].first;
119 }
120 
121 void farm() {
122     int i,j;
123         MonoVector v = MonoVector(false);
124         REP(i,n) {
125             lr[i].first = v.LeftStrangeId(a[i]) + 1;
126             v.insert(i,a[i]);
127         }
128         v.clear();
129         ROF(i,n-1,0){
130             int temp = v.LeftStrangeId(a[i]);
131             if(temp!=-1)lr[i].second=temp - 1;
132             else lr[i].second=n-1;
133             v.insert(i,a[i]);
134         }
135         int q[MAXN];
136         REP(i,n)q[i]=i;
137         sort(q, q+n, qcmp);
138         v = MonoVector(true);
139         int left = n;
140         ROF(j,n-1,0){
141             i = q[j];
142             while(lr[i].first < left){
143                 left --;
144                 v.insert(left , a[left]);
145             }
146             int ma = v.getLeftestValueWithIdNoBiggerThan(lr[i].second);
147 //            printf("%d [%d,%d], mi=%d, ma=%d, %d,%d\n",i,lr[i].first, lr[i].second, a[i], ma, a[i]*ma, lr[i].second - lr[i].first+1);
148             updateAns(lr[i].second - lr[i].first + 1 , 1LL*ma*a[i]);
149         }
150 
151 }
152 
153 int main() {
154     int i;
155     while(RD(n)!=EOF) {
156         MZ(ans);
157         REP(i,n) RD(a[i]);
158         farm();
159         FOR(i,1,n)cout<<ans[i]<<endl;
160     }
161     return 0;
162 }
View Code

(这题我自己没想出来,看别人题解,怎么全会用那个DP求l[i] r[i],for里面套while,看起来像O(n^2)的啊,想了一下发现好像并不是。我还是要学习一个。)

 

1003 瞬间移动 

写个暴力打表找规律,发现是组合数。

使m<n(不小于的话就交换一下,对称的), f(m,n) = C(m+n-2, m-1)

然后就变成怎么求大组合数取模了。这题的好像还不是很大,可以直接用逆元。再大的话要用Lucas定理加逆元了。

具体看我的另一题题解里有写:http://www.cnblogs.com/yuiffy/p/3909970.html

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 
14 #define MZ(array) memset(array, 0, sizeof(array))
15 #define MF1(array) memset(array, -1, sizeof(array))
16 #define MINF(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
24 #define WN(x) printf("%d\n",x);
25 #define RE  freopen("D.in","r",stdin)
26 #define WE  freopen("huzhi.txt","w",stdout)
27 #define MP make_pair
28 #define PB push_back
29 #define PF push_front
30 #define PPF pop_front
31 #define PPB pop_back
32 #define lowbit(x) ((x)&(-x))
33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
34     if(ed>=st)cout<<a[st];
35     int i;
36     FOR(i,st+1,ed)cout<<' '<<a[i];
37     puts("");
38 }
39 typedef long long LL;
40 typedef unsigned long long ULL;
41 const double PI=acos(-1.0);
42 const double EPS=1e-10;
43 inline int sgn(double &x) {
44     if(fabs(x) < EPS)return 0;
45     if(x < 0)return -1;
46     else return 1;
47 }
48 const int INF=0x3f3f3f3f;
49 const int NINF=0x80000001;
50 const int MAXN=111111;
51 const int MAXM=33;
52 const int MOD = 1000000007;
53 
54 int n,m;
55 
56 LL PowerMod(LL a, LL b) {
57     LL tmp = a, ret = 1;
58     while (b) {
59         if (b & 1) ret = ret * tmp % MOD;
60         tmp = tmp * tmp % MOD;
61         b >>= 1;
62     }
63     return ret;
64 }
65 
66 LL calC(LL n,LL m){
67     m=n-m>m?m:n-m;
68     LL up=1,down=1;
69     int i;
70     for(i=1;i<=m;i++){
71         down*=i;
72         down%=MOD;
73         up*=(n-i+1);
74         up%=MOD;
75     }
76     return (up*PowerMod(down,MOD-2))%MOD;
77 }
78 
79 LL Lucas(LL n, LL m) {
80     if(m==0)return 1;
81     return (Lucas(n/MOD, m/MOD)*calC(n%MOD, m%MOD))%MOD;
82 }
83 
84 inline LL farm(){
85     int i,j;
86     if(n<m)swap(n,m);
87     ///f(x,y) = C(x+y-2,x-1)   (x>y)
88     LL re = 1;
89     return Lucas(n+m-2,n-1);
90 }
91 
92 int main(){
93     while(RD2(n,m)!=EOF){
94         n--;m--;
95         cout<<farm()<<endl;
96     }
97     return 0;
98 }
View Code

上面好像是用^(n-2)的那种逆元,下面我又搞了一个exgcd逆元的:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 /**Header!**/ //{
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<cstring>
  7 #include<algorithm>
  8 #include<cmath>
  9 #include<map>
 10 #include<set>
 11 #include<stack>
 12 #include<queue>
 13 using namespace std;
 14 
 15 #define MZ(array) memset(array, 0, sizeof(array))
 16 #define MF1(array) memset(array, -1, sizeof(array))
 17 #define MINF(array) memset(array, 0x3f, sizeof(array))
 18 #define REP(i,n) for(i=0;i<(n);i++)
 19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 20 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 21 #define RD(x) scanf("%d",&x)
 22 #define RD2(x,y) scanf("%d%d",&x,&y)
 23 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 24 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 25 #define WN(x) printf("%d\n",x);
 26 #define RE  freopen("D.in","r",stdin)
 27 #define WE  freopen("huzhi.txt","w",stdout)
 28 #define MP make_pair
 29 #define PB push_back
 30 #define PF push_front
 31 #define PPF pop_front
 32 #define PPB pop_back
 33 #define lowbit(x) ((x)&(-x))
 34 #define cindiao ios_base::sync_with_stdio(0)
 35 #define fcout(x,y) cout << fixed << setprecision(x) << (y) << endl
 36 typedef long long LL;
 37 typedef unsigned long long ULL;
 38 typedef pair<int,int> PII;
 39 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 40     if(ed>=st)cout<<a[st];
 41     int i;
 42     FOR(i,st+1,ed)cout<<' '<<a[i];
 43     puts("");
 44 }
 45 template <class T> inline T quickPow(T p,T e,const T &M){
 46     LL ret = 1;
 47     for(; e > 0; e >>= 1){
 48         if(e & 1) ret = (ret * p) % M;
 49         p = (p * p) % M;
 50     } return (T)ret;
 51 }
 52 template <class T> inline T gcd(const T &a,const T &b){return (b==0) ? a : gcd(b,a%b);}
 53 template <class T> inline T niyuan(const T &a, const T &M){return quickPow(a,M-2,M);}
 54 template <class T> inline T exgcd(const T &a,const T &b,T &x,T &y) {
 55     if (!b) {x=1,y=0;return a;}
 56     T ret=exgcd(b,a%b,x,y), t;
 57     t=x,x=y,y=t-a/b*y;
 58     return ret;
 59 }
 60 template <class T> inline T niyuanex(const T &a, const T &M){
 61     T x,y;
 62     exgcd(a,M,x,y);
 63     return (x+M)%M;
 64 }
 65 inline LL calC(const int &n,int m,const LL &MOD){
 66     m=(n-m>m)?m:(n-m);
 67     LL up=1,down=1;
 68     int i;
 69     for(i=1;i<=m;i++){
 70         down*=i;
 71         down%=MOD;
 72         up*=(n-i+1);
 73         up%=MOD;
 74     }
 75     return (up*niyuanex(down, MOD))%MOD;
 76 }
 77 inline LL Lucas(const int &n,const int &m, const int &MOD) {
 78     if(m==0)return 1;
 79     return (1LL * Lucas(n/MOD, m/MOD, MOD)*calC(n%MOD, m%MOD, MOD))%MOD;
 80 }
 81 const int gx[4] = {-1,0,1,0};
 82 const int gy[4] = {0,1,0,-1};
 83 const double PI=acos(-1.0);
 84 //}
 85 const double EPS=1e-10;
 86 inline int sgn(double &x) {
 87     if(fabs(x) < EPS)return 0;
 88     if(x < 0)return -1;
 89     else return 1;
 90 }
 91 const int INF=0x3f3f3f3f;
 92 const int NINF=0x80000001;
 93 const int MAXN=111111;
 94 const int MAXM=33;
 95 const int MOD = 1000000007;
 96 
 97 int n,m;
 98 
 99 inline LL farm(){
100     int i,j;
101     if(n<m)swap(n,m);
102     ///f(x,y) = C(x+y-2,x-1)   (x>y)
103     LL re = 1;
104     return Lucas(n+m-2,n-1,MOD);
105 }
106 
107 int main(){
108     while(RD2(n,m)!=EOF){
109         n--;m--;
110         cout<<farm()<<endl;
111     }
112     return 0;
113 }
View Code

 

 

 

1005 区间交

优先队列题。

把区间[Li,Ri]按照Li从小到大排序。

然后依次把区间加入候选集,把他们的Ri加入优先队列,记住最小的Ri。

加到够k个以后,每次就要看是否能更新答案了。

k个区间的交集,区间[L,R],L就是最新加入的那个Li,R就是记着的最小的Ri。

如果光用优先队列来找最小Ri的话,会超时,我们来优化一下,就只在优先队列中存最大的k个Ri,不存太多的Ri。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 24 #define WN(x) printf("%d\n",x);
 25 #define RE  freopen("D.in","r",stdin)
 26 #define WE  freopen("huzhi.txt","w",stdout)
 27 #define MP make_pair
 28 #define PB push_back
 29 #define PF push_front
 30 #define PPF pop_front
 31 #define PPB pop_back
 32 #define lowbit(x) ((x)&(-x))
 33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 34     if(ed>=st)cout<<a[st];
 35     int i;
 36     FOR(i,st+1,ed)cout<<' '<<a[i];
 37     puts("");
 38 }
 39 typedef long long LL;
 40 typedef unsigned long long ULL;
 41 const double PI=acos(-1.0);
 42 const double EPS=1e-10;
 43 inline int sgn(double &x) {
 44     if(fabs(x) < EPS)return 0;
 45     if(x < 0)return -1;
 46     else return 1;
 47 }
 48 const int INF=0x3f3f3f3f;
 49 const int NINF=0x80000001;
 50 const int MAXN=111111;
 51 const int MAXM=33;
 52 const int MOD = 1000000007;
 53 
 54 struct Node {
 55     int l,r;
 56     inline bool operator<(const Node &y)const {
 57         return l<y.l;
 58     }
 59 };
 60 
 61 int n,k,m;
 62 int a[MAXN];
 63 Node b[MAXN];
 64 map<int,int> pq;
 65 LL sm[MAXN];
 66 inline LL farm() {
 67     int i;
 68     LL ans=0;
 69     sort(b,b+m);
 70     sm[0] = 0;
 71     FOR(i,1,n)sm[i] = sm[i-1] + a[i];
 72     pq.clear();
 73     int minR = INF;
 74     REP(i,k-1) {
 75         pq[b[i].r]++;
 76         minR = min(minR, b[i].r);
 77     }
 78     FOR(i,k-1,m-1) {
 79         int L = b[i].l;
 80         int R = b[i].r;
 81         R = min(R,minR);
 82         if(L<=R)ans = max(ans, sm[R] - sm[L-1]);
 83 //        printf("%d,%d,%d,%d,%d,%lld\n",b[i].l, b[i].r, L,R,pq.size(),ans);
 84         if(minR < b[i].r) {
 85             map<int,int>::iterator it = pq.begin();
 86             it->second--;
 87             if(it->second<=0) {
 88                 pq.erase(it);
 89                 pq[b[i].r]++;
 90                 it = pq.begin();
 91 //                printf("%d,%d\n",it->first, it->second);
 92                 minR = it->first;
 93             }else pq[b[i].r]++;
 94 
 95         }
 96 
 97     }
 98     return ans;
 99 }
100 
101 int main() {
102     int i;
103     while(RD3(n,k,m)!=EOF) {
104         FOR(i,1,n) RD(a[i]);
105         REP(i,m) RD2(b[i].l,b[i].r);
106         cout<<farm()<<endl;
107     }
108     return 0;
109 }
View Code

 

1006 中位数计数

前缀和?

思路:枚举每个数作为中位数,如果能O(n)算出有多少个区间以它为中位数,就无敌。想到用前缀和的思想,统计比它大、比它小的数的个数,能行。

用类似前缀和的思想,枚举每个数a[i]作为中位数,从它往左扫一遍,

设定一个变量x,当遇到一个比a[i]大的数,x++,遇到比a[i]小的数,x--。用一个数组统计各种x的出现次数,b[x]++。

再往右扫一遍,用另一个数组c来统计。

假如b[0]=5,可以得知,有5个点x=0,x=0说明比a[i]大的数 和 比a[i]小的数 一样多,这个区间就要以a[i]为中位数,b[0]=5说明有5个这样的区间。

假如b[3]=2,c[-3]=3,那么以a[i]为中位数的区间个数,可以加上b[3]*c[-3],因为左边多3个比a[i]大的,右边多3个比a[i]小的,正好抵消,他们组成的区间还是以a[i]为中位数。

就按照这个理论来一顿统计,就行啦。

因为数组不能有负数下标,x可以以8000为初始值。

注意各个数不相同,然后它设定偶数个数的话中位数为中间两个数的平均值,所以偶数个数组成的区间就不用管了,只算奇数个数组成的区间,特殊处理一下。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define ROF(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 24 #define WN(x) printf("%d\n",x);
 25 #define RE  freopen("D.in","r",stdin)
 26 #define WE  freopen("huzhi.txt","w",stdout)
 27 #define MP make_pair
 28 #define PB push_back
 29 #define PF push_front
 30 #define PPF pop_front
 31 #define PPB pop_back
 32 #define lowbit(x) ((x)&(-x))
 33 template<class T>inline void OA(const T &a,const int &st,const int &ed) {
 34     if(ed>=st)cout<<a[st];
 35     int i;
 36     FOR(i,st+1,ed)cout<<' '<<a[i];
 37     puts("");
 38 }
 39 typedef long long LL;
 40 typedef unsigned long long ULL;
 41 const double PI=acos(-1.0);
 42 const double EPS=1e-10;
 43 inline int sgn(double &x) {
 44     if(fabs(x) < EPS)return 0;
 45     if(x < 0)return -1;
 46     else return 1;
 47 }
 48 const int INF=0x3f3f3f3f;
 49 const int NINF=0x80000001;
 50 const int MAXN=8111;
 51 const int MAXM=33;
 52 const int MOD = 1000000007;
 53 
 54 int n;
 55 int a[MAXN];
 56 int ans[MAXN];
 57 
 58 inline void lisanhua() {
 59     int b[MAXN];
 60     int i;
 61     map<int,int> mp;
 62     REP(i,n)b[i]=a[i];
 63     sort(b,b+n);
 64     REP(i,n)mp[b[i]]=i;
 65     REP(i,n)a[i]=mp[a[i]];
 66 }
 67 
 68 void gank(int st, int ed, int step,bool dao, int flag,int myi, int sum[2][MAXN*2]) {
 69     int j;
 70     int now = 8000;
 71     bool fg=1;
 72     if(!dao) {
 73         for(j = st; j<=ed; j++) {
 74             if(a[j]<a[myi])now--;
 75             else now++;
 76             sum[fg][now]++;
 77             fg^=1;
 78         }
 79     } else {
 80         for(j = st; j>=ed; j--) {
 81             if(a[j]<a[myi])now--;
 82             else now++;
 83             sum[fg][now]++;
 84             fg^=1;
 85         }
 86     }
 87 }
 88 
 89 void farm() {
 90     int i,j,k;
 91 //    lisanhua();
 92 //    OA(a,0,n-1);
 93     REP(i,n) {
 94         int lsum[2][MAXN*2];
 95         int rsum[2][MAXN*2];
 96         MZ(lsum);
 97         MZ(rsum);
 98 //        gank(i-2,0,2,true,0,i,lsum);
 99         gank(i-1,0,123,true,666,i,lsum);
100 //        gank(i+2,n-1,2,false,0,i,rsum);
101         gank(i+1,n-1,456,false,888,i,rsum);
102         ans[i]=1 + lsum[0][8000]+rsum[0][8000];
103         REP(k,2) {
104             REP(j,n) {
105 //                printf("%d,%d,%d,%d\n",lsum[k][8000+j],rsum[k][8000-j],lsum[k][8000-j],rsum[k][8000+j]);
106                 if(lsum[k][8000+j] && rsum[k][8000-j]) {
107                     ans[i]+=lsum[k][8000+j]*rsum[k][8000-j];
108                 }
109                 if(j!=0) {
110                     if(lsum[k][8000-j] && rsum[k][8000+j]) {
111                         ans[i]+=lsum[k][8000-j]*rsum[k][8000+j];
112                     }
113                 }
114             }
115         }
116     }
117 }
118 
119 int main() {
120     int i;
121     while(RD(n)!=EOF) {
122         REP(i,n) RD(a[i]);
123         farm();
124         OA(ans,0,n-1);
125     }
126     return 0;
127 }
View Code

 

posted @ 2016-05-23 22:05  带鱼Yuiffy  阅读(379)  评论(0编辑  收藏  举报