计数转换器c++咋改

计数转换器
时间限制:1秒 内存限制:128M
题目描述
小可发明了一个计数转换器!对于一个序列,小可每使用一次计数转换器,这个序列就会发生一次转换,每个数字都会被替换成相应的出现次数。
比如对于序列1 2 1 1 3,使用一次计数转换器就会变成3 1 3 3 1。
小可使用了许多次计数转换器。现在小可需要多次查询某些元素在第k次使用计数转换器后的值。
输入描述
第一行一个正整数t(1≤t≤1000),代表有t组输入。
对于每组输入,第一行一个正整数n(1≤n≤2000),代表序列长度。
第二行n个正整数a​i​​ (1≤ai≤n),代表这个序列
第三行一个正整数q(1≤q≤10^5 ),代表有q次询问。
接下来q行,每行两个正整数x,k(1≤x≤n,0≤k≤10^9
​​ ),代表需要输出位置x的元素在第k次使用计数转换器后的值。
保证所有输入的n的总和不超过2000,所有输入的q的总和不超过10^5
输出描述
对于每组输入,输出每次询问的答案。
样例输入
2
7
2 1 1 4 3 1 2
4
3 0
1 1
2 2
6 1
2
1 1
2
1 0
2 1000000000
样例输出
1
2
3
3
1
2

主体部分怎么改才能不时间超限啊,求解答

这是我的代码{

#include
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int a[2005];
        for(int i=1; i<=n; i++){
            cin>>a[i];
        }
        int q;
        cin>>q;
        while(q--){
            int t[2005]={0},e[2005]={0},b[2005];
            for(int i=1; i<=n; i++){
                b[i]=a[i];
            }
            int c,d;
            cin>>c>>d;
            while(d--){
                memset(t,0,sizeof(t));
                for(int i=1; i<=n; i++){
                    t[b[i]]++;
                }
                int te=0;
                for(int i=1; i<=n; i++){
                    if(e[i]!=b[i]){
                        te=1;
                        break;
                    }
                }
                if(te==0){
                    break;
                }
                for(int i=1; i<=n; i++){
                    b[i]=t[b[i]];
                    e[i]=t[b[i]];
                }
            }
            cout<return 0;
}


}

你需要分析你的代码复杂度,看看是否存在可以优化的地方。在这种情况下,一个可能的改进是每次计算后都存储一个临时数组,这会导致额外的空间开销。相反,你可以使用一个数组来表示原始数组,但也要在每次计算后将其更新为新数组。这样,你就可以避免额外的空间开销,从而减少时间复杂度。

另一个可能的改进是,你可以使用一个多维数组来存储每个数字出现的次数。这样,你就不需要在每个计算循环中重新计算它们。通过这种方式,你可以减少循环的数量,减少时间复杂度。

下面是一个根据上述改进所编写的示例代码:

#include<bits/stdc++.h>
using namespace std;

int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int a[2005],cnt[2005][2005]={0};
for(int i=1; i<=n; i++){
cin>>a[i];
}
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
cnt[i][j] = 0;
}
}
for(int i=1; i<=n; i++){
int x = a[i];
for(int j=1; j<=n; j++){
if(j == x){
cnt[i][j] = cnt[i-1][x] + 1;
}else{
cnt[i][j] = cnt[i-1][j];
}
}
}
int q;
cin>>q;
while(q--){
int x,k;
cin>>x>>k;
for(int i=1; i<=n; i++){
if(cnt[n][i] == 0){
cnt[n][i] = cnt[n][i-1];
}
}
while(k--){
int temp = a[x];
a[x] = cnt[n][a[x]];
cnt[n][temp]--;
}
cout<<a[x]<<endl;
}
}
return 0;
}


在这个版本的代码中,我们使用多维数组来存储每个数字出现的次数。我们首先将所有计数器初始化为0,然后遍历原始数组。对于每个数字,我们将其对应的计数器增加1。接下来,我们使用一个类似的循环来处理所有查询。对于每个查询,我们将计数器数组中的所有值更新为其前一个值。然后,我们使用一个循环来更新原始数组,以便将指定位置的数字替换为其出现次数。最后,我们输出该位置的数字。

通过这些改进,我们可以显著降低时间复杂度,从而避免 Time Limit Exceeded 的问题。

``c++


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        int a[2005];
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        int q;
        cin >> q;
        while (q--) {
            int b[2005], t[2005] = {0}, e[2005] = {0};
            for (int i = 1; i <= n; i++) {
                b[i] = a[i];
            }
            int c, d;
            cin >> c >> d;
            map<int, int> cnt;
            for (int i = 1; i <= n; i++) {
                cnt[b[i]]++;
            }
            while (d--) {
                int stable = 1;
                for (int i = 1; i <= n; i++) {
                    t[i] = cnt[b[i]];
                    if (e[i] != t[i]) {
                        stable = 0;
                    }
                }
                if (stable) {
                    break;
                }
                for (int i = 1; i <= n; i++) {
                    b[i] = t[b[i]];
                    e[i] = t[b[i]];
                }
            }
            cout << b[c] << endl;
        }
    }
    return 0;
}

这个最后应该都会变成固定的,比如1 2 1 1 3最后变成3 2 3 3 2就不变了,2 1 1 4 3 1 2变成4 3 3 4 4 3 4。