bx值
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Problem Description
对于一个n个数的序列a1,a2,...,an
,从小到大排序之后为ap1,ap2,...,apn
,定义它的bx值为满足api≠api−1
+1,1<i<=n的i 的个数。
给定n个数的一个排列,你需要计算它所有连续子序列的bx值之和。
给定n个数的一个排列,你需要计算它所有连续子序列的bx值之和。
Input
输入第一行包括一个正整数T,表示数据组数。
对于每组数据,第一行一个整数n,第二行n个整数,表示n个数的一个排列。
1 <= T= < 20
1 <= n <= 100000
1 <= ai <= n
对于每组数据,第一行一个整数n,第二行n个整数,表示n个数的一个排列。
1 <= T= < 20
1 <= n <= 100000
1 <= ai <= n
Output
对每组数据输出一个整数表示答案。
Sample Input
2
3
1 2 3
4
3 1 4 2
Sample Output
0
5
分析:思维题。用总对数减去不符合条件的对数即可;
而不符合条件的必定是大小连续的两个数;
标记连续大小的两个数位置posx<posy,答案减去posx*(n-posy+1),因为包含这两个数的串都要答案减1;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 #define all(x) x.begin(),x.end() const int maxn=1e5+10; const int N=5e2+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;} ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=qmul(f,p,mo)%mo;p=qmul(p,p,mo)%mo;q>>=1;}return f;} int n,m,k,t,pos[maxn]; int main() { int i,j; while(~scanf("%d",&t)) { while(t--) { scanf("%d",&n); rep(i,1,n)scanf("%d",&j),pos[j]=i; ll ret=0; rep(i,2,n)ret+=1LL*(n-i+1)*(i-1); rep(i,1,n-1)ret-=1LL*min(pos[i],pos[i+1])*(n-max(pos[i],pos[i+1])+1); printf("%I64d ",ret); } } return 0; }