Niu Ke Practice 68

A. Niu Niu's mex

n, q ≤ 1 0 5, 0 ≤ ai <n and ai are different from each other n, q≤10 ^5, 0≤a i<n and a_i are different from each other n,q105,0to i<n and aiMutually not with the same
last two conditions are very important, the latter two conditions is transformed intoa natural number within a range minimum is not present is equal to not the natural number smallest occurring within the intervalto the interval[l, r] [l,[l,r ] only needs to calculate[1, l − 1] and [r + 1, n] [1,l-1] and [r+1,n][1,l1 ] sum [ r+1,n ] The smallest natural number in the interval. Directly preprocess the prefix suffix andpay attention to the boundarybecause0 ≤ ai <n 0\leq a_i<n0ai<n Just letpre[0]=suc[n+1]=nto

//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;    
    
}

Because it is very easy to lose sight of the above important conditions in daily blindness , it is not as elegant and violent as the above-Mo team

//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. Niuniu arithmetic

It is found that when n ≥ 199999 n \geq 199999n1 9 9 9 9 9 The answer must be0 00 .
So we only need to preprocessn <199999 n <199999n<1 9 9 9 9 9 answer to the.
Preprocessing prefix sum and prefix product directly calculate the answer.

#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;    
    
}

C. Niuniu's undirected graph

It is not difficult to see that what is required is the number of mutually reachable points through edges whose length is not greater than L.
For edges greater than L, we can regard it as having no such edge. We use union search to maintain the number of connected block points.
Put the query and the edge together, sort and process it

#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;    
}

The topic of Niuke.com feels pretty good, but the evaluation machine is very teary.
Come on~

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/108562922