2019牛客暑期多校训练营(第三场)

目录

B 、Crazy Binary String  (思维)

 D 、Big Integer ( 数论 )

 F 、Planting Trees(思维+单调队列)

 H、 Magic Line  (计算几何)

J、 LRU management (模拟)


B 、Crazy Binary String  (思维)

题意:

计算最长的01子串和子序列,其中01数量相同。

分析:

对于子串那么直接将0制成-1,1还是1计算前缀和,然后相减为零的最大长度即为答案

对于子序列也就是计算最小的0 或 1 的数量。

 

#include 

using namespace std;

const int maxn=1e5+10;

char s[maxn];
int pre[maxn];
map mp;

int main(){

    int n;
    scanf("%d%s",&n,s+1);
    int ans1=0,ans2=0;
    for(int i=1;i<=n;i++){
        pre[i]=pre[i-1]+(s[i]=='0'?-1:1);
        ans2+=s[i]-'0';
        if(mp[pre[i]]==0&&pre[i]!=0){
            mp[pre[i]]=i;
        }else{
            ans1=max(ans1,i-mp[pre[i]]);
        }
    }
    printf("%d %d\n",ans1,min(ans2<<1,(n-ans2)<<1));
    return 0;
}

 D 、Big Integer ( 数论 )

题意:

定义\tiny A(n) 表示有n个1,计算\tiny A(i^j){\color{Red} mod}p==0 ,i,j 范围均为1e9

分析:

2019牛客暑期多校训练营(第三场)_第1张图片

 2019牛客暑期多校训练营(第三场)_第2张图片

 

#include

#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;

const int inf=0x3f3f3f3f;

ll quick_mul(ll a,ll b,ll mod){
    ll res=0;
    while(b){
        if(b&1) res=(res+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return res;
}

ll quick_pow(ll a,ll b,ll mod){
    ll ans=1;
    while(b){
        if(b&1) ans=quick_mul(ans,a,mod)%mod;
        a=quick_mul(a,a,mod)%mod;
        b>>=1;
    }
    return ans;
}

ll quick_pow(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1) ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}

ll yin[1000000][2];

int main(){
    #ifdef io
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif

    int T;
    scanf("%d",&T);
    while(T--){
        ll p,n,m;
        scanf("%lld%lld%lld",&p,&n,&m);
        if(p==2||p==5){
            printf("0\n");
            continue;
        }
        ll xun=6ll*(p-1);
        ll temp=xun;
        for(ll i=1;i*i<=temp;i++){
            if(temp%i==0) {
                if(quick_pow(10,i,9ll*p)==1){
                    xun=min(xun,i); break;
                }else if(quick_pow(10,temp/i,9ll*p)==1){
                    xun=min(xun,temp/i);
                }
            }
        }
        int tot=0;
        for(ll i=2;i*i<=xun;i++){
            if(xun%i==0){
                tot++;
                int cnt=0;
                yin[tot][0]=i;
                yin[tot][1]=0;
                while(xun%i==0){
                    xun/=i;
                    yin[tot][1]++;
                }
            }
        }
        if(xun>1){
            yin[++tot][0]=xun;
            yin[tot][1]=1;
        }
        ll ans=0;
        for(int j=1;j<=32&&j<=m;j++){
            ll tmp=1;
            for(int k=1;k<=tot;k++){
                tmp=tmp*quick_pow(yin[k][0],(yin[k][1]+j-1)/j);
            }
            ans+=n/tmp;
        }
        ll tmp=1;
        for(int k=1;k<=tot;k++){
            tmp=tmp*yin[k][0];
        }
        ans+=n/tmp*max(0ll,m-33+1);
        printf("%lld\n",ans);
    }
    return 0;
}

 F 、Planting Trees(思维+单调队列)

题意:

给出一个矩阵,计算最大的矩形使得所有元素的差值在m之内。

分析:

\tiny O(n^3)的做法,首先固定上下行进行枚举,计算出每列的最大最小值,用单调队列进行维护,

同时注意每次不满足条件的时候进行更新。还有注意细节

#include

#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;

const int inf=0x3f3f3f3f;

const int maxn=505;

int a[maxn][maxn];
int mn[maxn],mx[maxn];
int q1[maxn],q2[maxn];

int main(){
    #ifdef io
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif

    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
        int ans=0;
        for(int u=1;u<=n;u++){
            for(int i=1;i<=n;i++) mx[i]=0,mn[i]=inf;
            for(int d=u;d<=n;d++){
                int l1,l2,r1,r2;
                l1=l2=r1=r2=0;
                int tmp=0;
                for(int i=1;i<=n;i++){
                    mn[i]=min(mn[i],a[d][i]);
                    mx[i]=max(mx[i],a[d][i]);
                    while(l1mn[i]) r1--;
                    while(l2m) {
                        if(q1[l1]

 H、 Magic Line  (计算几何)

题意:

将给出的点用一条直线分为两堆,计算正好平分所有点的一条直线,输出坐标,其中坐标均为整数

分析:

将所有点排个序取中间点即可。然后选取个很大的点,狗成一条直线,就能正好评分。

#include

using namespace std;

const int maxn=1e3+10;

struct node{
    int x,y;
    bool operator < (const node p){
        if(x==p.x) return y>p.y;
        return x

J、 LRU management (模拟)

题意:

给出一系列操作进行模拟;

分析:

注意的就是用STL的时候要用unordered_map,因为map是基于红黑树实现的,underorder_map是基于哈希表实现的,所以一个复杂度是logn,一个是1.

还要注意如果用c++加速读入的话不能和scanf一起读。

#include

#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define PI acos(-1.0)
#define E exp(1.0)
//#define io
using namespace std;

const int inf=0x3f3f3f3f;

struct node{
    string s;
    int v;
};

typedef list::iterator iter;

int main(){
    #ifdef io
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif

    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--){
        int n,m;
        cin>>n>>m;
        list lis;
        unordered_map mp;
        int cnt=0;
        while(n--){
            int op,v;
            string s;
            cin>>op>>s>>v;
            if(op==0){
                int ans;
                if(mp.find(s)!=mp.end()){
                    auto it=mp[s];
                    lis.erase(it);
                    lis.push_back(node{s,it->v});
                    it=lis.end();it--;
                    mp[s]=it;
                    ans=it->v;
                }else{
                    lis.push_back(node{s,v});
                    cnt++;
                    auto it=lis.end();
                    it--;
                    mp[s]=it;
                    ans=v;
                    if(cnt>m){
                        auto it=lis.begin();
                        mp.erase(it->s);
                        lis.pop_front();
                        cnt--;
                    }
                }
                printf("%d\n",ans);
            }else{
                if(mp.find(s)==mp.end()){
                    printf("Invalid\n");
                }else{
                    auto it=mp[s];
                    if(v==0){
                        printf("%d\n",it->v);
                    }else if(v==1){
                        it++;
                        if(it==lis.end()) printf("Invalid\n");
                        else printf("%d\n",it->v);
                    }else{
                        if(it==lis.begin()){
                            printf("Invalid\n");
                        }else{
                            it--;
                            printf("%d\n",it->v);
                        }
                    }
                }
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(总结)