J - Different Integers 牛客多校

这题正解不是莫队,但是确实看起来比较像莫队,所以就当练手。
这题卡常卡的厉害,cout都会tle。
莫队一般都是求区间的结果,这个恰好相反,取非区间的结果。
先全处理出来一共有多少,把中间的减掉,如果中间把某个值的元素全部占有,结果就减一。

#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
#include<iomanip>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>

using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const ll mod = 1e9 + 7;
const double eps = 1e-5;
const double PI = acos(-1);
void acc_ios()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
}
struct node
{
    
    
    int l, r, id, pos;
};
node qu[maxn];
int vis[maxn], res[maxn], a[maxn], ans;
bool cmp(node a, node b)//可以优化200ms左右的排序方法,还挺关键的
{
    
    
    if(a.pos == b.pos)
    {
    
    
        if(a.pos % 2)
            return a.r < b.r;
        else
            return a.r > b.r;
    }
    else
        return a.l < b.l;
}
void add(int x)
{
    
    
    vis[a[x]]--;
    //cout<<"a"<<a[x]<<endl;
    if(vis[a[x]] == 0) ans--;
}
void del(int x)
{
    
    
    vis[a[x]]++;
   // cout<<"d"<<a[x]<<endl;
    if(vis[a[x]] == 1)
        ans++;
}
int main()
{
    
    
    //acc_ios();
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF)
    {
    
    
        ans = 0;
        memset(vis, 0, sizeof(vis));
        vis[0] = 1000;
        for(int i = 1; i <= n; i++)
        {
    
    
            scanf("%d", &a[i]);
            vis[a[i]]++;
            if(vis[a[i]] == 1)
                ans++;
        }
        int x = sqrt(n);
        for(int i = 0; i < m; i++)
        {
    
    
            scanf("%d%d", &qu[i].l, &qu[i].r);
            qu[i].l++, qu[i].r--;
            qu[i].id = i;
            qu[i].pos = qu[i].l / x;
        }
        //cout<<ans<<endl;
        int l = 1, r = 0;
        sort(qu, qu + m, cmp);
        for(int i = 0; i < m; i++)
        {
    
    
            int L = qu[i].l, R = qu[i].r;
            //cout<<L<<" "<<R<<endl;
            while(l < L) del(l++);
            while(l > L) add(--l);
            while(r < R) add(++r);
            while(r > R) del(r--);
            res[qu[i].id] = ans;
        }
        for(int i = 0; i < m; i++)
            printf("%d\n", res[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43891021/article/details/106162878
今日推荐