Sona NBUT - 1457 CodeForces 220B Little Elephant and Array 【莫队 + 离散化】

NBUT 1457 是要求区间内不同的数出现次数的立方和

CodeForces 220B 是要求区间内不同的数出现次数等于其本身个数和。

由于两题给的数都是 1 ~ 1e9, 而且n的范围是1 ~ 1e5, 所以都需要离散化一下。这两题也就十分相似。

NBUT 1457

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#define ll __int64
using namespace std;
const int N = 100103;
int n, m, pos[N];
int c[N], sub[N] ;
ll s[N], ans;
inline ll cube(ll x) {
    return x*x*x;
}
struct node {
    int l, r, id;
    ll ans;
}q[N];
bool cmp(node a, node b) {
    if(pos[a.l] == pos[b.l]) {
        return a.r < b.r;
    }
    return a.l < b.l;
}
bool cmpId(node a, node b) {
    return a.id < b.id;
}
inline void scanf_(int &num) {
    char in;
    bool neg=false;
    while(((in=getchar()) > '9' || in<'0') && in!='-') ;
    if(in=='-') {
        neg=true;
        while((in=getchar()) >'9' || in<'0');
    }
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
    if(neg)
        num=0-num;
}
void Update(int index, int tp) {
    ans -= cube(s[c[index]]);
   // ans -= (ll)s[c[index]]*s[c[index]]*s[c[index]];
    s[c[index]] += tp;
    ans += cube(s[c[index]]);
    //ans += (ll)s[c[index]]*s[c[index]]*s[c[index]];
}
void solve() {
    for(int i=1, l=1,r=0; i<=m; i++) {
        if(q[i].l==q[i].r) {
            q[i].ans=1;
            continue;
        }
        for( ; r<q[i].r; r++) {
            Update(r+1, 1);
        }
        for( ; r>q[i].r; r--) {
            Update(r, -1);
        }
        for( ; l<q[i].l; l++) {
            Update(l, -1);
        }
        for( ; l>q[i].l; l--) {
            Update(l-1, 1);
        }
        q[i].ans = ans;
    }
}
int main() {
    while(scanf("%d", &n)!=EOF) {
        memset(s, 0, sizeof(s)), ans = 0;
        int block = (int)sqrt(n*1.0);
        for(int i=1; i<=n; i++) scanf_(c[i]), pos[i] = (i-1)/block + 1,sub[i] = c[i];
        scanf_(m);
        for(int i=1; i<=m; i++) {
//            scanf("%d%d", &q[i].l, &q[i].r);
            scanf_(q[i].l);
            scanf_(q[i].r);
            q[i].id = i;
        }
        sort(sub+1, sub+n+1);
        int Size = unique(sub+1, sub+n+1) - (sub+1);
        for(int i=1; i<=n; i++) {
            c[i] = lower_bound(sub+1, sub+Size+1, c[i]) - (sub+1);
        }
        sort(q+1, q+1+m, cmp);
        solve();
        sort(q+1, q+1+m, cmpId);
        for(int i=1; i<=m; i++) {
            printf("%I64d\n",q[i].ans);
        }
    }
    return 0;
}

CodeForces 220B

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#define ll long long
using namespace std;
const int N = 200103;
int n, m, pos[N];
int c[N], sub[N], b[N];
ll s[N], ans;
bool vis[N];
struct node {
    int l, r, id;
    ll ans;
}q[N];
bool cmp(node a, node b) {
    if(pos[a.l] == pos[b.l]) {
        return a.r < b.r;
    }
    return a.l < b.l;
}
bool cmpId(node a, node b) {
    return a.id < b.id;
}
inline void scanf_(int &num) {
    char in;
    bool neg=false;
    while(((in=getchar()) > '9' || in<'0') && in!='-') ;
    if(in=='-') {
        neg=true;
        while((in=getchar()) >'9' || in<'0');
    }
    num=in-'0';
    while(in=getchar(),in>='0'&&in<='9')
        num*=10,num+=in-'0';
    if(neg)
        num=0-num;
}
void Update(int index, int tp) {
    s[c[index]] += tp;
    if(s[c[index]] == b[index]+tp) ans--;
    if(s[c[index]]==b[index]) ans++;
}
void solve() {
    for(int i=1, l=1,r=0; i<=m; i++) {
        for( ; r<q[i].r; r++) {
            Update(r+1, 1);
        }
        for( ; r>q[i].r; r--) {
            Update(r, -1);
        }
        for( ; l<q[i].l; l++) {
            Update(l, -1);
        }
        for( ; l>q[i].l; l--) {
            Update(l-1, 1);
        }
        q[i].ans = ans;
    }
}
int main() {
    while(scanf("%d%d", &n, &m)!=EOF) {
        memset(s, 0, sizeof(s)), ans = 0;
        int block = (int)sqrt(n*1.0), sum = 0;
        for(int i=1; i<=n; i++){
            scanf("%d", &c[i]);
            sub[i] = c[i];
            b[i] = c[i];
            pos[i] = (i-1)/block + 1;
        }
        for(int i=1; i<=m; i++) {
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].id = i;
        }
        sort(sub+1, sub+n+1);
        int Size = unique(sub+1, sub+n+1) - (sub);
        for(int i=1; i<=n; i++) {
            c[i] = lower_bound(sub+1, sub+Size, c[i]) - (sub);
        }
        sort(q+1, q+1+m, cmp);
        solve();
        sort(q+1, q+1+m, cmpId);
        for(int i=1; i<=m; i++) {
            printf("%lld\n",q[i].ans);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/khn64/article/details/81185181