zoukankan      html  css  js  c++  java
  • Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板

    D. Mahmoud and Ehab and another array construction task

    题意:
    给出一个数组 a[],要你构造出一个互质的字典序最小的数组 b[],且 b[] 的字典序要大于等于 a[] 。
    tags:
    预处理出 1e5 个素数,然后对于第 i 个数,它应该不包含前面 n-1 个数含有的质因子,满足这个条件后,我们贪心取最大的即可。且如果当前已经大于数组 a[] 了,那后面的就都贪心取最小的质数。

    // CF 959D
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 20000005;
    
    const int M=2000005;  // M : size
    bool mark[M];  // true : prime number
    int pp[N], cnt;
    void sieve_prime()
    {
        memset(mark, true, sizeof(mark));
        mark[0] = mark[1] = false;
        for(int i=2; i<=sqrt(M); i++) {
            if(mark[i]) {
                for(int j=i*i; j<M; j+=i)
                    mark[j]=false;
            }
        }
        rep(i,2,M-1) if(mark[i]) pp[++cnt] = i;
    }
    
    int n, a[N], b[N];
    bool vis[M];
    void get(int x) {
        for(int i=1; i<=cnt && pp[i]<=x; ++i) {
            while(x%pp[i]==0) vis[pp[i]]=true, x/=pp[i];
        }
    }
    bool is(int x) {
        for(int i=1; i<=cnt && pp[i]<=x; ++i)
            if(vis[pp[i]])
        {
            if(x%pp[i]==0) return false;
        }
        return true;
    }
    int main()
    {
        sieve_prime();
        scanf("%d", &n);
        rep(i,1,n) scanf("%d", &a[i]);
        bool flag = false;
        int  ca = 1;
        rep(i,1,n)
        {
            if(flag) {
                for( ; vis[pp[ca]]; ++ca) ;
                vis[pp[ca]]=true;
                b[i] = pp[ca];
                continue;
            }
            if(i==1) b[1]=a[1], get(b[1]);
            else {
                for(int j=a[i]; ; ++j)
                    if(is(j))
                {
                    get(j);   b[i]=j;
                    if(j>a[i]) flag = true;
                    break;
                }
            }
        }
        rep(i,1,n) printf("%d ", b[i]);
    
        return 0;
    }
    
    

    F. Mahmoud and Ehab and yet another xor task

    题意:
    n 个数,q 个询问,每次询问有 l, x 。 询问前 l 个数里,有多少个子序列的异或和为 x 。
    tags:
    第一次见线性基的问题。。很有意思。
    参考了博客 https://blog.csdn.net/qaq__qaq/article/details/53812883
    我们把询问按 l 排序,对于每个询问我们把 a[1] ~ a[l] 都插入到线性基里。首先看线性基能否异或出 x ,然后看线性基里有几个数,如有 k 个数,那答案就是 2^(l-k) 。
    可以这样考虑,如果线性基可以异或出 x ,线性基里有 k个数,那在另外 l - k 个数里取出一个数 y ,我们对于 y 取或不取有两种可能。如取 y ,那只要异或出 x 即可;如不取 y ,那就异或出 x^y 即可(肯定可以异或出 x^y 的,因为线性基的异或域和原序列的异或域相同)。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005, mod = 1e9+7;
    
    ll  fpow(ll a, ll b) {
        ll ret = 1;
        for(a%=mod; b; b>>=1, a=a*a%mod) if(b&1) ret = ret*a%mod;
        return ret;
    }
    
    struct L_B
    {
        long long d[61], p[61];
        int cnt;
        L_B() {
            memset(d,0,sizeof(d));
            memset(p,0,sizeof(p));
            cnt=0;
        }
        bool Insert(long long val) { //插入
            for (int i=60;i>=0;i--)
                if (val&(1LL<<i)) {
                    if (!d[i]) { d[i]=val; break; }
                    val ^= d[i];
                }
            return val>0;
        }
        bool is_in(long long val) { //存在性
            for(int i=60; i>=0; --i) {
                if(val&(1LL<<i)) {
                    if(d[i]) val ^= d[i];
                }
            }
            return val==0;
        }
        long long query_max() { //最大值
            long long ret=0;
            for (int i=60;i>=0;i--)
                if ((ret^d[i])>ret)
                    ret^=d[i];
            return ret;
        }
        long long query_min() { //最小值
            for (int i=0;i<=60;i++)
                if (d[i]) return d[i];
            return 0;
        }
        void rebuild() {  //求 k 小值前加
            for (int i=60;i>=0;i--)
                for (int j=i-1;j>=0;j--)
                    if (d[i]&(1LL<<j))
                        d[i]^=d[j];
            for (int i=0;i<=60;i++)
                if (d[i]) p[cnt++]=d[i];
        }
        long long kthquery(long long k) { //k小值
            long long ret=0;
            if (k>=(1LL<<cnt))
                return -1;
            for (int i=60;i>=0;i--)
                if (k&(1LL<<i))
                    ret^=p[i];
            return ret;
        }
    } LB;
    L_B merge(const L_B &n1,const L_B &n2) //合并
    {
        L_B ret=n1;
        for (int i=60;i>=0;i--)
            if (n2.d[i])
                ret.Insert(n2.d[i]);
        return ret;
    }
    
    int a[N];
    ll  ans[N];
    pair< int, pair< int , int >  > Q[N];
    int main()
    {
        int n, q;  scanf("%d%d", &n, &q);
        rep(i,1,n) scanf("%d", &a[i]);
        rep(i,1,q) scanf("%d%d", &Q[i].fi, &Q[i].se.fi), Q[i].se.se=i;
        sort(Q+1, Q+1+q);
        int now = 1;
        rep(i,1,q)
        {
            for( ; now<=Q[i].fi; ++now) LB.Insert(a[now]);
            if(!LB.is_in(Q[i].se.fi)) {
                ans[Q[i].se.se] = 0;
                continue;
            }
            int cnt = 0;
            per(j,60,0) if(LB.d[j]) ++cnt;
            ans[Q[i].se.se] = fpow(1LL*2, Q[i].fi-cnt);
        }
        rep(i,1,q) printf("%lld
    ", (ans[i]+mod)%mod);
    
        return 0;
    }
    
  • 相关阅读:
    初级知识点四——设计模式六大原则
    初级知识点三——面向对象的三大特性
    初级知识点二——C#值传递
    初级知识点一——C#中的值类型与引用类型
    Unity资源引用问题
    Git在windows上的设置详解
    Unity中接收服务器消息并广播事件的实现
    Sphinx 自动化文档
    MAC Pro 同时安装 Python2 和 Python3
    数据中心网络架构演进 — 云网融合
  • 原文地址:https://www.cnblogs.com/sbfhy/p/8732904.html
Copyright © 2011-2022 走看看