Práctica Niu Ke 68

A. Niu Niu's mex

n, q ≤ 1 0 5, 0 ≤ ai <n y ai son diferentes entre sí n, q≤10 ^ 5, 0≤a i <n y a_i son diferentes entre sí n ,q1 05 ,0para yo<n y unayoMutuamente no con las mismas
dos últimas condiciones son muy importantes, las dos últimas condiciones se transforman enun número natural dentro de un rango mínimo no está presente es igual a no es el número natural más pequeño que ocurre dentro del intervaloal intervalo[l, r] [l,[ l ,r ] solo necesita calcular[1, l - 1] y [r + 1, n] [1, l-1] y [r + 1, n][ 1 ,l-1 ] suma [ r+1 ,n ] El número natural más pequeño del intervalo. Preprocese directamente el sufijo del prefijo ypreste atención al límiteporque0 ≤ ai <n 0 \ leq a_i <n0unayo<n Simplemente dejapre[0]=suc[n+1]=na

//O(n)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N],pre[N],suc[N];
int n,q;
int main()
{
    
    
    cin>>n>>q;
    pre[0]=suc[n+1]=n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) pre[i]=min(pre[i-1],a[i]);
    for(int i=n;i;i--) suc[i]=min(suc[i+1],a[i]);
    while(q--)
    {
    
    
        int l,r;
        cin>>l>>r;
        cout<<min(pre[l-1],suc[r+1])<<'\n';
    }
    return 0;    
    
}

Debido a que es muy fácil perder de vista las condiciones importantes anteriores en la ceguera diaria , no es tan elegante y violento como el equipo de Mo anterior.

//O(nsqrt(n))
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100010;
int cnt[N],sz,pos[N];
struct node
{
    
    
    int l,r,id;
    bool operator<(const node& o) const 
    {
    
    
        if(pos[l]==pos[o.l]) return r<o.r;
        else return pos[l]<pos[o.l];
    }
}q[N];
int a[N],n,m;
int ans[N],res;
void add(int k)
{
    
    
    cnt[a[k]]++;
    while(cnt[res]) res++;
}
void sub(int k)
{
    
    
    cnt[a[k]]--;
    if(!cnt[a[k]]&&a[k]<=res) res=a[k];
}
int main()
{
    
    
    cin>>n>>m;
    sz=sqrt(n);
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>a[i];
        pos[i]=i/sz;
    }
    for(int i=1;i<=m;i++)
    {
    
    
        cin>>q[i].l>>q[i].r;
        q[i].id=i;
    }
    sort(q+1,q+1+m);
    int l=1,r=0;
    for(int i=1;i<=m;i++)
    {
    
    
       while(l<q[i].l) sub(l++);
       while(l>q[i].l) add(--l);
       while(r<q[i].r) add(++r);
       while(r>q[i].r) sub(r--);
       ans[q[i].id]=res;
    }
    for(int i=1;i<=m;i++) cout<<ans[i]<<'\n';
    return 0;
}

B. Aritmética de Niuniu

Se encuentra que cuando n ≥ 199999 n \ geq 199999norte1 9 9 9 9 9 La respuesta debe ser0 00 .
Así que solo necesitamos preprocesarn <199999 n <199999norte<1 9 9 9 9 9 respuesta a la.
El preprocesamiento de la suma de prefijo y el producto de prefijo calculan directamente la respuesta.

#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=200010;
const ll mod=199999;
ll s1[N],s2[N];
string p="199999";
void init()
{
    
    
    for(int i=1;i<mod;i++)
        s1[i]=(s1[i-1]+1ll*i*(i+1)/2*i%mod)%mod;
    s2[0]=1;
    for(int i=1;i<mod;i++)
        s2[i]=s2[i-1]*i%mod*s1[i]%mod;
}
int main()
{
    
    
    int T=1;
    init();
    cin>>T;
    
    while(T--)
    {
    
    
        string a;
        cin>>a;
        if(a.size()>6||a.size()==6&&a>p)
        {
    
    
            cout<<0<<'\n';
            continue;
        }
        reverse(a.begin(),a.end());
        int base=1,n=0;
        for(auto t:a)
        {
    
    
            n+=base*int(t-'0');
            base*=10;
        }
        cout<<s2[n]<<'\n';
    }
    return 0;    
    
}

Gráfico no dirigido de C. Niuniu

No es difícil ver que lo que queremos es el número de puntos mutuamente alcanzables a través de aristas con una longitud no mayor que L.
Para aristas mayores que L, podemos considerar que no tiene tal arista. Usamos la búsqueda de unión para mantener el número de puntos de bloque conectados.
Junte la consulta y el borde, ordene y procese

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100010,M=500010;
struct node
{
    
    
    int op;
    int a,b,w;
    int id;
    bool operator<(const node& o)const 
    {
    
    
        if(w==o.w) return op<o.op;
        return w<o.w;
    }
}e[2*M];
int n,m;
int q[M],k;
ll ans[M],now;
unsigned int SA, SB, SC; int LIM;
unsigned int rng61(){
    
    
    SA ^= SA << 16;
    SA ^= SA >> 5;
    SA ^= SA << 1;
    unsigned int t = SA;
    SA = SB;
    SB = SC;
    SC ^= t ^ SA;
    return SC;
}
void gen(){
    
    
    scanf("%d%d%d%u%u%u%d", &n, &m, &k, &SA, &SB, &SC, &LIM);
    for(int i = 1; i <= m; i++){
    
    
        e[i].a = rng61() % n + 1;
        e[i].b = rng61() % n + 1;
        e[i].w = rng61() % LIM;
    }
    for(int i = 1; i <= k; i++){
    
    
        q[i] = rng61() % LIM;
    }
}
int p[N],sz[N];
int find(int x)
{
    
    
    return x==p[x]?x:p[x]=find(p[x]);
}
int main()
{
    
    
    gen();
    for(int i=1;i<=m;i++) e[i].op=1;
    for(int i=1;i<=n;i++) p[i]=i,sz[i]=1;
    for(int i=1;i<=k;i++)
    {
    
    
        e[i+m].op=2;
        e[i+m].w=q[i];
        e[i+m].id=i;
    }
    sort(e+1,e+1+m+k);
    for(int i=1;i<=m+k;i++)
    {
    
    
        if(e[i].op==1)
        {
    
    
            int pa=find(e[i].a),pb=find(e[i].b);
            if(pa!=pb)
            {
    
    
                p[pa]=pb;
                now+=1ll*sz[pa]*sz[pb];
                sz[pb]+=sz[pa];
            }
        }
        else
            ans[e[i].id]=now;
    }
    ll res=0;
    for(int i=1;i<=k;i++) res^=ans[i];
    cout<<res<<'\n';
    return 0;    
}

El tema de Niuke.com se siente bastante bien, pero la máquina de evaluación es muy llorosa.
Vamos ~

Supongo que te gusta

Origin blog.csdn.net/Fighting_Peter/article/details/108562922
Recomendado
Clasificación