• 2019 The Preliminary Contest for ICPC China Nanchang National Invitational(A 、H 、I 、K 、M)


     A. PERFECT NUMBER PROBLEM

    题目链接:https://nanti.jisuanke.com/t/38220

    题意:

    输出前五个完美数

    分析:

    签到。直接百度完美数输出即可

    #include<bits/stdc++.h>
    #define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
    #define sd(n) scanf("%d",&n)
    #define sdd(n,m) scanf("%d%d",&n,&m)
    #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define pd(n) printf("%d
    ", (n))
    #define pdd(n,m) printf("%d %d
    ", n, m)
    #define pld(n) printf("%lld
    ", n)
    #define pldd(n,m) printf("%lld %lld
    ", n, m)
    #define sld(n) scanf("%lld",&n)
    #define sldd(n,m) scanf("%lld%lld",&n,&m)
    #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
    #define sf(n) scanf("%lf",&n)
    #define sff(n,m) scanf("%lf%lf",&n,&m)
    #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define mm(a,n) memset(a, n, sizeof(a))
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define ll long long
    #define numm ch - 48
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define pi 3.14159265358979323
    #define debug(x) cout << #x << ": " << x << endl
    #define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
    #define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
    #define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
    using namespace std;
    template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);flag&&(res=-res);}
    template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a*b/gcd(a,b);}
    ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
    ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
    
    const int N = 2e5 + 10;
    
    int main()
    { 
        printf("6
    28
    496
    8128
    33550336
    ");
        return 0;
    }
    View Code

     

     H. Coloring Game

    题目链接:https://nanti.jisuanke.com/t/38227

    题意:

    给你个 2 * N 的网格 , 你有up(), down(), left(), right(), left up(), left down(), right up(), right down () 八个路径走到下一个网格

    网格原来是全白色的 , 你每经过一个网格它就会变黑色 (白变黑 , 黑变黑). 要求你从左上角走到右下角 , 问能有多少种不同的配色方案(只要有一处网格颜色不同即为不同方案)

    分析:

    由于起点和终点固定 , 所以对于第一列和最后一列网格不同配色方案为 2 * 2 = 4 ; 而对于起点与终点之间的网格每一列都只有三种状态(黑白 、 白黑 、 黑黑),所以答案为 4 * 3 ^ (n - 2) % MOD;

    快速幂跑一遍。。。

    #include<bits/stdc++.h>
    #define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
    #define sd(n) scanf("%d",&n)
    #define sdd(n,m) scanf("%d%d",&n,&m)
    #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define pd(n) printf("%d
    ", (n))
    #define pdd(n,m) printf("%d %d
    ", n, m)
    #define pld(n) printf("%lld
    ", n)
    #define pldd(n,m) printf("%lld %lld
    ", n, m)
    #define sld(n) scanf("%lld",&n)
    #define sldd(n,m) scanf("%lld%lld",&n,&m)
    #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
    #define sf(n) scanf("%lf",&n)
    #define sff(n,m) scanf("%lf%lf",&n,&m)
    #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define mm(a,n) memset(a, n, sizeof(a))
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define ll long long
    #define numm ch - 48
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    #define pi 3.14159265358979323
    #define debug(x) cout << #x << ": " << x << endl
    #define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
    #define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
    #define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
    using namespace std;
    template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);flag&&(res=-res);}
    template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a*b/gcd(a,b);}
    ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
    ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
    
    const int N = 2e5 + 10;
    
    int main()
    {
        ll n;
        cin >> n;
        if(n == 1){
            cout << 1 << endl;
            return 0;
        }
        cout << 4 * pow_mod(3 , n - 2 , MOD) % MOD << endl;
        return 0;
    }
    View Code

    I. Max answer

    题目链接:https://nanti.jisuanke.com/t/38228

    题意:

    给一个长为n(n <= 500000)的数组a, 对每个区间,求区间和乘区间最小值的最大值(1e≤ a≤1e5).

    分析:

    这道题乍一看像是单调栈的模板题 , 但很可惜的是 ai 的取值可以为负数 , 所以对于以 ai 为最小值的区间 , 若 ai 为负数 , 要找到最小区间和 , 若为 ai 为正数 , 要找到最大区间和

    对于正数ai,利用单调栈寻找以ai为最小值的区间,利用前缀和数组求区间和再*ai 即结果(ai 为正数 , ai为区间最小值)

    先用单调栈求出以a[i]为最小值能够延伸的左端点L[i]和右端点R[i] , 然后对于每个正数,我们用该数乘以这个区间和。区间和用前缀和来求,对于每个数所能影响的最大区间我们已经求出来了。对于负数来说,我们需要求在它右区间的最小前缀和减去左区间的最大前缀和 , 因为只有它的区间和最小对应的这个区间的value值才最大,又由区间和=sum[j]-sum[i]可知,sum[j]最小,sum[i]最大时才能时这个区间和最小,所以问题的关键转化为寻找最小的sum[j]和最大的sum[i]

    对于右区间的最小前缀和,以及左区间的最大前缀和我们用线段树来求

    #include<bits/stdc++.h>
    #define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
    #define sd(n) scanf("%d",&n)
    #define sdd(n,m) scanf("%d%d",&n,&m)
    #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define pd(n) printf("%d
    ", (n))
    #define pdd(n,m) printf("%d %d
    ", n, m)
    #define pld(n) printf("%lld
    ", n)
    #define pldd(n,m) printf("%lld %lld
    ", n, m)
    #define sld(n) scanf("%lld",&n)
    #define sldd(n,m) scanf("%lld%lld",&n,&m)
    #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
    #define sf(n) scanf("%lf",&n)
    #define sff(n,m) scanf("%lf%lf",&n,&m)
    #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define mm(a,n) memset(a, n, sizeof(a))
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define ll long long
    #define numm ch - 48
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define pi 3.14159265358979323
    #define debug(x) cout << #x << ": " << x << endl
    #define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
    #define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
    #define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
    using namespace std;
    template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);flag&&(res=-res);}
    template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a*b/gcd(a,b);}
    ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
    ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
    
    const int N = 5e5 + 10;
    ll sum[N],a[N];
    ll maxn[N << 2],minn[N << 2];
    void build(int l,int r,int root)
    {
        if(l==r)
        {
            maxn[root]=minn[root]=sum[l];
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,root<<1);
        build(mid+1,r,root<<1|1);
        maxn[root]=max(maxn[root<<1],maxn[root<<1|1]);
        minn[root]=min(minn[root<<1],minn[root<<1|1]);
    }
    ll qmax(int l,int r,int root,int ql,int qr)
    {
        if(l>=ql&&r<=qr)
            return maxn[root];
        int mid=l+r>>1;
        ll ans=-INF;
        if(mid>=ql)
            ans=qmax(l,mid,root<<1,ql,qr);
        if(mid<qr)
            ans=max(ans,qmax(mid+1,r,root<<1|1,ql,qr));
        return ans;
    }
    ll qmin(int l,int r,int root,int ql,int qr)
    {
        if(l>=ql&&r<=qr)
            return minn[root];
        int mid=l+r>>1;
        ll ans=INF;
        if(mid>=ql)
            ans=qmin(l,mid,root<<1,ql,qr);
        if(mid<qr)
            ans=min(ans,qmin(mid+1,r,root<<1|1,ql,qr));
        return ans;
    }
    int LL[N],RR[N],st[N];
    int main()
    {
        ios;
        int n;
        cin >> n;
        rep(i ,1 ,n)
        cin >> a[i],sum[i] = sum[i-1]+a[i];
        build(1,n,1);
        int top=0;
        rep(i ,1 ,n)
        {
            while(top&&a[st[top]]>a[i])
                RR[st[top--]]=i-1;
            st[++top]=i;
        }
        while(top)
            RR[st[top--]]=n;
        for(int i=n;i>=1;i--)
        {
            while(top&&a[st[top]]>a[i])
                LL[st[top--]]=i+1;
            st[++top]=i;
        }
        while(top)
            LL[st[top--]]=1;
        ll ans = -INF;
        rep(i ,1 ,n)
        {
            if(a[i]>0)
                ans=max(ans,a[i]*(sum[RR[i]]-sum[LL[i]-1]));
            else
                ans=max( ans,a[i]*( qmin(1,n,1,i,RR[i])-qmax(1,n,1,LL[i],i)) );
        }
           cout << ans << endl;
        return 0;
    }
    View Code

    K. MORE XOR

    题目链接:https://nanti.jisuanke.com/t/38230

    题意:

    分析:

    对于 L - R 内的每一个数 ai 只有当 ai 出现次数为奇数时才会对结果做出贡献 , 所以我们可以先暴力打表找找规律

    打表函数:

    void f(int l,int r)
    {
        for(int i=l; i<=r; i++)
            cnt[i]++;
    }
    void g(int l,int r)
    {
        for(int x=l; x<=r; x++)
            for(int y=x; y<=r; y++)
                f(x,y); 
    }
    void w(int l,int r)
    {
        for(int x=l; x<=r; x++)
            for(int y=x; y<=r; y++)
                g(x,y);
    }
    打表

    记录每个数字出现的次数,奇数次说明这个数存在于答案中,偶数次相当于对答案没有贡献。打表找规律发现跟4的倍数有关,所以我们预处理以4为分组的异或和,然后O(1)输出结果就可以了。

    #include<bits/stdc++.h>
    #define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
    #define sd(n) scanf("%d",&n)
    #define sdd(n,m) scanf("%d%d",&n,&m)
    #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define pd(n) printf("%d
    ", (n))
    #define pdd(n,m) printf("%d %d
    ", n, m)
    #define pld(n) printf("%lld
    ", n)
    #define pldd(n,m) printf("%lld %lld
    ", n, m)
    #define sld(n) scanf("%lld",&n)
    #define sldd(n,m) scanf("%lld%lld",&n,&m)
    #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
    #define sf(n) scanf("%lf",&n)
    #define sff(n,m) scanf("%lf%lf",&n,&m)
    #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define mm(a,n) memset(a, n, sizeof(a))
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define ll long long
    #define numm ch - 48
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define pi 3.14159265358979323
    #define debug(x) cout << #x << ": " << x << endl
    #define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
    #define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
    #define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
    using namespace std;
    template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
    for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);flag&&(res=-res);}
    template<typename T>void Out(T x){if(x<0)putchar('-'),x=-x;if(x>9)Out(x/10);putchar(x%10+'0');}
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a*b/gcd(a,b);}
    ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}
    ll fact_pow(ll n,ll p){ll res=0;while(n){n/=p;res+=n;}return res;}
    
    const int N = 1e5 + 10;
    
    ll a[N] , sum[N];
    int n , q;
    int main()
    {
        int t;
        sd(t);
        while(t--)
        {
            cin >> n;
            rep(i ,1 ,n)
            sld(a[i]);
            sd(q);
            rep(i , 1 ,n)
            {
                if(i <= 4) sum[i] = a[i];
                else
                    sum[i] = sum[i - 4] ^ a[i];
            }
            while(q--)
            {
                int l , r;
                sdd(l , r);
                int len = r - l + 1 ;
                ll ans ;
                if(len % 4 == 0)
                    ans = 0;
    
                else if(len % 4 == 1)
                {
                    ans = sum[r];
                    if(l - 4 > 0)
                        ans ^= sum[l - 4];
                }
                
                else if(len % 4 == 2)
                {
                    ans = sum[r] ^ sum[r - 1];
                    if(l - 3 > 0)
                        ans ^= sum[l - 3];
                    if(l - 4 > 0)
                        ans ^= sum[l - 4];
                }
    
                else if(len % 4 == 3)
                {
                    ans = sum[r - 1];
                    if(l - 3 > 0)
                        ans ^= sum[l - 3];
                }
                pld(ans);
            }
        }
        return 0;
    }
    View Code

    M. Subsequence

    题目链接:https://nanti.jisuanke.com/t/38232

    题意:

    给你个母串S , 在给你 N 个字符串 T , 为 T 是否为 S 的子序列

    分析:

    这道题时间卡得有点过分 , 我用 string 读取字符串竟然分分钟 Tle 。。。

    首先我们用 nex[ i ][ j ] 表示 S 串中 i 字符之后的离它最近的 j 字符的位置 , 从后往前预处理 S串中每一个字符 i 的下一位字符 j 的位置

    然后输入 T 串判断 T 串当前字符 now1和 T 串下一个字符 T[i] 在主串中的位置是否会合法(即判断nex[now1][ T[i] - 'a'] 是否会小于 len(字符串下标从0开始) )

    #include<bits/stdc++.h>
    #define ios std::ios::sync_with_stdio(false) , std::cin.tie(0) , std::cout.tie(0)
    #define sd(n) scanf("%d",&n)
    #define sdd(n,m) scanf("%d%d",&n,&m)
    #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define pd(n) printf("%d
    ", (n))
    #define pdd(n,m) printf("%d %d
    ", n, m)
    #define pld(n) printf("%lld
    ", n)
    #define pldd(n,m) printf("%lld %lld
    ", n, m)
    #define sld(n) scanf("%lld",&n)
    #define sldd(n,m) scanf("%lld%lld",&n,&m)
    #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
    #define sf(n) scanf("%lf",&n)
    #define sff(n,m) scanf("%lf%lf",&n,&m)
    #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
    #define rep(i,a,n) for (int i=a;i<=n;i++)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define mm(a,n) memset(a, n, sizeof(a))
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    #define ll long long
    #define numm ch - 48
    #define INF 0x3f3f3f3f
    #define pi 3.14159265358979323
    #define debug(x) cout << #x << ": " << x << endl
    #define debug2(x, y)          cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<< endl;
    #define debug3(x, y, z)       cout <<#x<<": "<<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl;
    #define debug4(a, b, c, d)    cout <<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl;
    using namespace std;
    template<typename T>void read(T &res)
    {
        bool flag=false;
        char ch;
        while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
        for(res=numm; isdigit(ch=getchar()); res=(res<<1)+(res<<3)+numm);
        flag&&(res=-res);
    }
    template<typename T>void Out(T x)
    {
        if(x<0)putchar('-'),x=-x;
        if(x>9)Out(x/10);
        putchar(x%10+'0');
    }
    ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a;
    }
    ll lcm(ll a,ll b)
    {
        return a*b/gcd(a,b);
    }
    ll pow_mod(ll x,ll n,ll mod)
    {
        ll res=1;
        while(n)
        {
            if(n&1)res=res*x%mod;
            x=x*x%mod;
            n>>=1;
        }
        return res;
    }
    ll fact_pow(ll n,ll p)
    {
        ll res=0;
        while(n)
        {
            n/=p;
            res+=n;
        }
        return res;
    }
    const int N = 1e5 + 10;
    int nex[N][30];
    int now[N];
    char s[N] , t[N];
    void init(int &len)
    {
        len = strlen(s);
        rep(i , 0 , len - 1) now[i] = len;
        for(int i = len - 1 ; i >= 0 ; i --)
        {
            for(int j = 0 ; j < 26 ;j ++)
            {
                nex[i][j] = now[j];
            }
            now[s[i] - 'a'] = i;
        }
    }
    int main()
    {
    
        scanf("%s" , s);
        int len ;
        init(len);
        int n;
        read(n);
        while(n --)
        {
        scanf("%s" , t);
            int len2 = strlen(t);
            int flag = 0;
            int now1 = now[t[0] - 'a'];
            if(len < len2)
            {
                puts("NO");
                continue;
            }
            if(now1 >= len)
            {
                puts("NO");
                continue;
            }
            for(int i = 1 ; i < len2 ; i++)
            {
                now1 = nex[now1][t[i] - 'a'];
                if(now1 >= len){flag = 1 ;break;}
            }
            if(flag)    puts("NO");
            else    puts("YES");/*123*/
        }
        return 0;
    }
    View Code
    凡所不能将我击倒的,都将使我更加强大
  • 相关阅读:
    http和https的区别与联系
    HTTP请求/响应报文结构
    Java并发包中Lock的实现原理
    Java多线程基础——Lock类
    深入理解Java并发之synchronized实现原理
    ConcurrentHashMap 的实现原理
    【Java集合学习】HashMap源码之“拉链法”散列冲突的解决
    趣谈Java变量的可见性问题
    Java中CAS详解
    LockSupport的park和unpark的基本使用,以及对线程中断的响应性
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/11639189.html
Copyright © 2020-2023  润新知