题解 P1637 【三元上升子序列】
本题暴力十分好打,只需
但显然,对于奇技淫巧优化,
这个玩意可以刺激cpu并发,
比暴力不知道快到哪里去了
Code:
// luogu-judger-enable-o2
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
#define R register
using namespace std;
typedef long long ll;
inline char gc() {
static char buf[100000], *p1 = buf, *p2 = buf;
return (p1 == p2) && (p2 = (p1 = buf) +
fread (buf, 1, 100000, stdin), p1 == p2)? EOF: *p1++;
}
#define int ll
inline ll read(){
ll res=0,f=1;
char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=gc();}
while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=gc();}
return res*f;
}
void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10|'0');
}
const int N=30005;
ll ans,n,sum[N],sum2[N],a[N];
#define debug(x) (cout << "#x = " << (x) << endl)
signed main(){
n=read();
for(R int i=1;i<=n;i++) a[i]=read();
for(R int i=1;i<=n;i++){
R int j = 1;
R int a1 = 0, a2 = 0;
R int a3 = 0, a4 = 0;
R int a5 = 0, a6 = 0;
R int a7 = 0, a8 = 0;
for (; j + 8 <= i; j += 8) {
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a2;
if (a[j + 2] < a[i]) ++a3;
if (a[j + 3] < a[i]) ++a4;
if (a[j + 4] < a[i]) ++a5;
if (a[j + 5] < a[i]) ++a6;
if (a[j + 6] < a[i]) ++a7;
if (a[j + 7] < a[i]) ++a8;
}
ll k = i - j;
// cout << "!" << j << " " << k << endl;
switch (k) {
case 0: break;
case 1:
if (a[j] < a[i]) ++a1;
break;
case 2:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a2;
break;
case 3:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a2;
if (a[j + 2] < a[i]) ++a3;
break;
case 4:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a1;
if (a[j + 2] < a[i]) ++a2;
if (a[j + 3] < a[i]) ++a3;
break;
case 5:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a1;
if (a[j + 2] < a[i]) ++a2;
if (a[j + 3] < a[i]) ++a3;
if (a[j + 4] < a[i]) ++a4;
break;
case 6:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a2;
if (a[j + 2] < a[i]) ++a3;
if (a[j + 3] < a[i]) ++a4;
if (a[j + 4] < a[i]) ++a5;
if (a[j + 5] < a[i]) ++a6;
break;
case 7:
if (a[j] < a[i]) ++a1;
if (a[j + 1] < a[i]) ++a1;
if (a[j + 2] < a[i]) ++a2;
if (a[j + 3] < a[i]) ++a3;
if (a[j + 4] < a[i]) ++a4;
if (a[j + 5] < a[i]) ++a5;
if (a[j + 6] < a[i]) ++a6;
break;
}
sum[i] += a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
// for(R int j=1;j<i;j++)
// if(a[j]<a[i]) sum[i]++;
}
for(R int i=1;i<=n;i++){
R int j = i + 1;
R int a1 = 0, a2 = 0;
R int a3 = 0, a4 = 0;
R int a5 = 0, a6 = 0;
R int a7 = 0, a8 = 0;
for (; j + 7 <= n; j += 8) {
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a2;
if (a[j + 2] > a[i]) ++a3;
if (a[j + 3] > a[i]) ++a4;
if (a[j + 4] > a[i]) ++a5;
if (a[j + 5] > a[i]) ++a6;
if (a[j + 6] > a[i]) ++a7;
if (a[j + 7] > a[i]) ++a8;
}
ll k = n - j + 1;
// cout << "!" << j << " " << k << endl;
switch (k) {
case 0: break;
case 1:
if (a[j] > a[i]) ++a1;
break;
case 2:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a2;
break;
case 3:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a2;
if (a[j + 2] > a[i]) ++a3;
break;
case 4:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a1;
if (a[j + 2] > a[i]) ++a2;
if (a[j + 3] > a[i]) ++a3;
break;
case 5:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a1;
if (a[j + 2] > a[i]) ++a2;
if (a[j + 3] > a[i]) ++a3;
if (a[j + 4] > a[i]) ++a4;
break;
case 6:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a2;
if (a[j + 2] > a[i]) ++a3;
if (a[j + 3] > a[i]) ++a4;
if (a[j + 4] > a[i]) ++a5;
if (a[j + 5] > a[i]) ++a6;
break;
case 7:
if (a[j] > a[i]) ++a1;
if (a[j + 1] > a[i]) ++a1;
if (a[j + 2] > a[i]) ++a2;
if (a[j + 3] > a[i]) ++a3;
if (a[j + 4] > a[i]) ++a4;
if (a[j + 5] > a[i]) ++a5;
if (a[j + 6] > a[i]) ++a6;
break;
}
sum2[i] += a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
// for(R int j=i+1;j<=n;j++)
// if(a[j]>a[i]) sum2[i]++;
}
for(R int i=1;i<=n;i++)
ans+=sum[i]*sum2[i];
return write (ans), 0;
}
/*
11
1 2 3 4 5 6 7 8 9 10 11
*/