求卡常
查看原帖
求卡常
679936
sunkuangzheng楼主2024/4/22 16:34

如题,不知道为什么 TLE on test 22。

经过一些 assert 发现 while(1) 内的执行次数不超过 2400 次就 TLE 了,不是复杂度问题。

看了一些别人 TLE on 22 的记录都是在卡常,但我真不知道我哪里常数大了。

/**
 *    author: sunkuangzheng
 *    created: 22.04.2024 15:14:57
**/
#include<bits/stdc++.h>
#ifdef DEBUG_LOCAL
#include <mydebug/debug.h>
#endif
using ll = long long;
const int N = 5e5+5;
using namespace std;
int T,n,a[N],f[N];
void los(){
    cin >> n,fill(f+1,f+n+1,0);
    vector<int> ans;
    for(int i = 0;i < n;i ++) cin >> a[i];
    auto sb = [&](int &x,int y){x = (x > y ? x - y : 0);};
    int ct = 0;
    while(1){
        int fg = 0;
        assert(++ct <= 2400);
        // for(int i = 0;i < n;i ++) sb(a[(i==n-1?0:i+1)],a[i]);
        for(int i = 0;i < n;i ++) a[(i+1)%n] = max(a[(i+1)%n] - a[i],0);
        for(int i = n;i <= n + 3;i ++) a[i] = a[i-n];
        for(int i = 0;i < n;i ++) if(a[i]&&a[(i+1)]&&a[(i+2)]&&a[(i+3)]) fg = 1;
        if(!fg) break;
    }for(int i = 0;i < n;i ++)
        if(a[i] && a[(i+1)%n]) sb(a[(i+1)%n],a[i]);
        else break;
    for(int i = 0;i < n;i ++)
        if(!a[i] && a[(i+1)%n]){
            ans.push_back((i+1)%n);
            if(a[(i+2)%n] && a[(i+3)%n]){
                int d = a[(i+2)%n] / a[(i+1)%n];
                ll k = 1ll * a[(i+2)%n] * d - 1ll * d * (d + 1) / 2 * (a[(i+1)%n]);
                if(a[(i+3)%n] > k) ans.push_back((i+3)%n);
            }
        }
    sort(ans.begin(),ans.end());
    cout << ans.size() << "\n";
    for(int i : ans) cout << i + 1 << " "; cout << "\n";
}int main(){
    ios::sync_with_stdio(0),cin.tie(0);
    for(cin >> T;T --;) los();
}
2024/4/22 16:34
加载中...