Codeforces Round 1024 (Div. 2)(A~D,补E)

A.Dinner Time

思路:经典if,else问题,发现\(a_i\)的值以p为周期且每p个值就为q。那么先看n是否为p的倍数,如果是,就看\(n/p*q\)是否等于m,等于就是YES,否则就是NO。如果不是倍数呢?那么就YES,你总可以另多的一部分为\(m-n/p*q\)

吐槽:没注意到\(a_i\)可以为负数,wa了一发test1。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l,r,w;
    friend bool operator<(const s& a, const s& b)
    {
        return a.w>b.w;
    };
};
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t=1;
    cin>>t;
    while(t--)
    { 
        ll n,m,p,q;
        cin>>n>>m>>p>>q;
        ll u=n/p;
        ll d=n%p;
        if(n%p==0)
        {
            if(u*q==m)cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        else cout<<"YES"<<endl;
    }
    return 0;
}

B.The Picky Cat

思路:\(a_1\)的可能只有\(a_1\)或者\(-a_1\),那么我们可以考虑尝试去枚举\(a_1\)为两种可能时其是否符合答案。对于一个确定的\(a_1\),数组里无非就三种\(a_i,(i>=2)\),怎么变都小于\(a_1\)\(a_i\);怎么变都大于\(a_1\)\(a_i\);可以变成大于或小\(a_1\)\(a_i\).不妨记入三种数的个数分别为cn1,cn2,cn3,如果中位数前面的数字个数为u,那么\(cn1<=u&&cn3+cn1>=u\)就一定为有合法解条件。于是检验两种可能得出答案即可

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l,r,w;
    friend bool operator<(const s& a, const s& b)
    {
        return a.w>b.w;
    };
};
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t=1;
    cin>>t;
    while(t--)
    { 
       ll n;
       cin>>n;
       vector<ll>a(n+5);
       for(ll i=1;i<=n;i++)cin>>a[i];
       ll l=-abs(a[1]);
       ll cn1,cn2;
       cn1=cn2=0;
       ll cn3=0;
       for(ll i=2;i<=n;i++)
       {
        if(abs(a[i])<l)cn1++;
        else if(-abs(a[i])>l)cn2++;
        else cn3++;
       }
       ll ok=0;
       ll u=(n+1)/2-1;
       if(cn1<=u&&cn1+cn3>=u)ok=1;
       l=-l;
       cn1=cn2=cn3=0;
        for(ll i=2;i<=n;i++)
       {
        if(abs(a[i])<l)cn1++;
        else if(-abs(a[i])>l)cn2++;
        else cn3++;
       }
        if(cn1<=u&&cn1+cn3>=u)ok=1;
       if(ok)cout<<"YES"<<endl;
       else cout<<"NO"<<endl;
    }
    return 0;
}

C.Mex in the Grid

思路:直接螺旋形构造就可以了,这个得自己手画下,我也不能给出很合理的证明

吐槽:一开始就盯帧了应该答案是以螺旋形构造就可以,但是没有证明

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll l,r,w;
    friend bool operator<(const s& a, const s& b)
    {
        return a.w>b.w;
    };
};
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t=1;
    cin>>t;
    while(t--)
    { 
       ll n;
       cin>>n;
       vector<vector<ll>>a(n+5,vector<ll>(n+5,0));
       ll l=1,r=n;
       ll k=n*n-1;
       while(1)
       {
        for(ll i=l;i<=r;i++)
        {
            a[l][i]=k;
            k--;
        }
        for(ll i=l+1;i<=r;i++)
        {
            a[i][r]=k;
            k--;
        }
        for(ll i=r-1;i>=l;i--)
        {
            a[r][i]=k--;
        }
        for(ll i=r-1;i>=l+1;i--)
        {
            a[i][l]=k--;
        }
        l++;
        r--;
        if(l>r)break;
       }
       for(ll i=1;i<=n;i++)
       {
        for(ll j=1;j<=n;j++)cout<<a[i][j]<<" ";
        cout<<endl;
       }
    }
    return 0;
}

D.Quartet Swapping

思路:这道题如果按最贪心的方法去冒泡排序得出的答案一定是对了,因为奇数位置上的数才能对应互相交换,偶数位置上的数才能对应互相交换。不妨想想最后四个数\(a_1,a_2,a_3,a_4\),如果\(a_1\)确定那么\(a_3\)也确定了,但是也许\(a_2\)\(a_4\)可以互换?但实际是固定的,应为如果两个能换时,就会有另一个位置上的数影响他,毕竟\(a_2\)\(a_4\)都在序列最后了,那么其值排序优先度一定弱于另一位置.好,至此就是思考如何暴力维护,本质上他每次只会移动两个数到最前面,其他数就保持原顺序即可,那么显然可以用链表结构来维护,所以每次去贪心用链表维护对应奇偶位最小的数即可,注意如果想要的数在末尾,可以先把他给转移出来,然后再统一方法处理,最后只会有三个数得直接读入,这时候用链表继续走即可

吐槽:写慢了,重点是把a数组和ans数组搞混了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
// struct s
// {
//     ll l,r,w;
//     friend bool operator<(const s& a, const s& b)
//     {
//         return a.w>b.w;
//     };
// };
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t = 1;
    cin >> t;
    while (t--)
    {
        ll n;
        cin >> n;
        vector<ll>a(n + 5, 0);
        for (ll i = 1; i <= n; i++)cin >> a[i];
        set<ll>f1, f2;
        for (ll i = 1; i <= n; i++)
        {
            if (i & 1)f1.insert(a[i]);
            else f2.insert( a[i]);
        }
        vector<ll>next(n + 5), sm(n + 5);
        a[n + 1] = n + 1;
        for (ll i = 1; i <= n; i++)
        {
            next[a[i]] = a[i + 1];
            sm[a[i]] = a[i - 1];
        }
        ll cnt = 1;
        ll dd = a[1];
        vector<ll>ans(n + 5, 0), vis(n + 5, 0);
        while (1)
        {
            if (n - cnt + 1 >= 4)
            {
                if (cnt % 2 == 0)swap(f1, f2);
                ll u = (*f1.begin());
                if (sm[u] == ans[cnt-1])
                {
                    ans[cnt] = u;
                    dd = next[u];
                }
                else
                {
                    if (next[u] == n + 1)
                    {
                        ll d1 = sm[u];
                        ll d2 = sm[d1];
                        ll d3 = sm[d2];
                        ll ff = sm[d3];
                        next[ff] = d1;
                        next[d1] = u;
                        next[u] = d3;
                        next[d3] = d2;
                        next[d2] = n + 1;
                        sm[d1] = ff;
                        sm[u] = d1;
                        sm[d3] = u;
                        sm[d2] = d3;
                    }
                    ll k1 = next[u];
                    ll k2 = next[k1];
                    ll kk = sm[u];
                    sm[k2] = kk;
                    next[kk] = k2;
                    ans[cnt] = u;
                    sm[u] = 0;
                    next[k1] = dd;
                    sm[dd] = k1;
                    dd = k1;
                }
                f1.erase(*f1.begin());
                if (cnt % 2 == 0)swap(f1, f2);
                cnt++;
            }
            else break;
        }
        for (ll i = 1; i <= n; i++)
        {
            if (next[i] == n + 1)
            {
                ll kk = n;
                ll cs = 3;
                while (cs--)
                {
                    ans[kk] = i;
                    kk--;
                    i = sm[i];
                }
                break;
            }
        }
        for (ll i = 1; i <= n; i++)cout << ans[i] << " ";
        cout << endl;
    }
    return 0;
}

附加:发现原来可以看逆序对奇偶性,特此补充一个答案。显然每次进行一次那个操作它对奇偶位置上的数的逆序对个数变化影响是一样的,那么最后得出的排序只要符合原逆序对个数奇偶性一样(因为排序后的逆序对个数为0,所以刚好是逆序对的奇偶性,正序对得算差值),那么就可以直接输出对应奇偶位置sort后的答案,否则先分别sort,然后看n奇偶性,直接选最优的换即可(如果n为奇数,那么换最后两个奇数位置上的最后两个数,否则就换偶数位置上的最后两个数)

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
const ll N=2e5+5;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
// struct s
// {
//     ll l,r,w;
//     friend bool operator<(const s& a, const s& b)
//     {
//         return a.w>b.w;
//     };
// };
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t = 1;
    cin >> t;
    while (t--)
    {
        ll n;
        cin>>n;
        vector<ll>odd(n+5),even(n+5),c(n+5,0);
        ll l=0,r=0;
        for(ll i=1;i<=n;i++)
        {
            ll x;
            cin>>x;
            if(i&1)odd[++l]=x;
            else even[++r]=x;
        }
        function<void(ll,ll)>add=[&](ll x,ll v)
        {
            for(ll i=x;i<=n;i+=lowbit(i))
            {
                c[i]+=v;
            }
        };
        function<ll(ll)>query=[&](ll x)
        {
            ll ans=0;
            for(ll i=x;i;i-=lowbit(i))ans+=c[i];
            return ans;
        };
        function<ll(vector<ll>&,ll)>ck=[&](vector<ll>&d,ll f)
        {
            ll ans=0;
            for(ll i=1;i<=f;i++)
            {
                add(d[i],1);
                ans+=query(n)-query(d[i]);
            }
            for(ll i=1;i<=f;i++)
            {
                add(d[i],-1);
            }
            return ans;
        };
        ll ok=0;
        if(ck(odd,l)%2==ck(even,r)%2)
        {
            ok=1;
        }
            sort(odd.begin()+1,odd.begin()+1+l);
            sort(even.begin()+1,even.begin()+r+1);   
            if(ok==0)
            {
                if(n&1)swap(odd[l],odd[l-1]);
                else swap(even[r],even[r-1]);
            }
            l=r=0;
            for(ll i=1;i<=n;i++)
            {
                if(i&1)cout<<odd[++l]<<" ";
                else cout<<even[++r]<<" ";
            }
            cout<<endl;
    }
    return 0;
}

E.23 Kingdom

思路:显然我们要求这个最大值,肯定是让每一个数值的第一个出现下标和最后一个出现小标尽可能地远,所以题目其实等价于所有数字出现的最后一个下标之和-所有数字第一个出现的下标之和的差值最大。加上\(a_i\)的限制,我们可以简单地想到从1开始向上维护数字是最佳的,那么可以用set来进行一种表示。首先用set存储1 ~ n,从左往右遍历数组,如果当前set中有小于等于\(a_i\)的数,那么说明当前cnt一定可以选中,其类似于动态维护了一个最优放置(如果cnt小于等于\(a_i\),说明之前小于等于他的值还可以选,那么此时选中cnt也不为过。如果cnt已经大于这个\(a_i\)且还有值,说明前面有比这个\(a_i\)大的数,这时候我们可以抽象的认为,大家选完这个数后立马重新分配到最优位置),选完后当前小于等于\(a_i\)的最大数记得erase掉。至此再做个后缀。注意前后缀都是维护到当前数的下标!!随后暴力遍历1~n的可能去加每个数的后缀-前缀,记得负数不加或者break。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<cstring>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#include<bitset>
#define ll                       long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> f;
//find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)//快速幂
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
// inline ll read()//快读
// {
//     register ll x = 0, f = 1;
//     char c = getchar();
//     while (c < '0' || c>'9')
//     {
//         if (c == '-') f = -1;
//         c = getchar();
//     }
//     while (c >= '0' && c <= '9')
//     {
//         x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
//         c = getchar();
//     }
//     return x * f;
// }
void fio()//加速流
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s
{
    ll w,l,r;
    friend bool operator<(const s& a, const s& b)
    {
        return a.w<b.w;
    };
};
ll e1[8] = { 0,1,0,-1,1,1,-1,-1 };
ll e2[8] = { 1,0,-1,0,1,-1,-1,1 };//前面四个为右边开始的逆时针,后面四个为角落
ll zs[2500000];
ll cnt = 0;
void ola(ll x)
{
    vector<bool>vis(x + 5);
    for (ll i = 2; i <= x; i++)
    {
        if (!vis[i])zs[++cnt] = i;
        for (ll j = 1; i * zs[j] <= x; j++)
        {
            vis[i * zs[j]] = 1;
            if (i % zs[j] == 0)break;
        }
    }
}
int main()
{
    fio();
    ll t=1;
   cin>>t;
    while(t--)
    {
       ll n;
       cin>>n;
       vector<ll>a(n+5);
       for(ll i=1;i<=n;i++)cin>>a[i];
       set<ll>f1,f2;
       for(ll i=1;i<=n;i++)f1.insert(i);
       f2=f1;
       vector<ll>pre(n+5,0),sub(n+5,0);
       ll cnt=1;
       for(ll i=1;i<=n;i++)
       {
        auto j=f1.upper_bound(a[i]);
        if(j==f1.begin())continue;
        j--;
        pre[cnt++]=i;
        f1.erase(*j);
       }
       cnt=1;
       for(ll i=n;i>=1;i--)
       {
        auto j=f2.upper_bound(a[i]);
        if(j==f2.begin())continue;
        j--;
        sub[cnt++]=i;
        f2.erase(*j);
       }
       ll ans=0;
       for(ll i=1;i<=n;i++)
       {
        ans+=max(0ll,sub[i]-pre[i]);
       }
       cout<<ans<<endl;
    }
    return 0;
}
posted @ 2025-05-12 08:23  长皆  阅读(191)  评论(0)    收藏  举报