Codeforces Round #631 (Div. 2) ABD

A题

题意:

给n个数据,m次操作,使得1~A,全都出现。如果其中有数据没在n里出现,就m--

思路:

模拟就行

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 998244353
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
const int maxn=1e3+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n,m;
int v[maxn];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        int a;mem(v,0);
        for(it i=0;i<n;i++){
            scanf("%d",&a);v[a]=1;
        }
        int maxx=0;
        for(it i=1;m;i++){
            if(v[i]==0){v[i]=1;m--;maxx=i;}
            else{maxx=i;}
        }
        for(it i=maxx+1;;i++){
            if(v[i]){maxx=i;}
            else{break;}
        }
        printf("%d\n",maxx);
    }
    return 0;
}

 

B题

题意:

给n个数据,这写数据范围,1<=a[i]<=n-1

问能不能割断,比如

2 1 3 4 | 2 1,这样左边就是1234,右边12

如果有输出全部,如果没有输出0

思路:

从前遍历,从后遍历,出现两次相同的数字就是不符合,如果没重复的个数达到最大值,记录位置。

再验证一下后面的数据是否符合条件,比如有可能2 1 3 4 1 1这种。

还有wa了一次是因为,如果从前遍历,从后遍历,相同位置,就输出一个即可,比如1 2 2 1

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 998244353
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
const int maxn=2e5+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t,n,m;
int a[maxn],vis[maxn];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        mem(vis,0);int f=1,maxx=-1;
        for(it i=1;i<=n;i++){
            scanf("%d",&a[i]);
            //vis[a[i]]++;
            if(maxx<a[i]){maxx=a[i];}
        }
        int ge=0;
        for(it i=1;i<=n;i++){
            if(vis[a[i]]==0){ge++;vis[a[i]]=1;}
            else{f=0;break;}
            if(ge==maxx){ge=i;break;}
        }
        int ff=2,g2=0;mem(vis,0);
        for(it i=n;i>=1;i--){
            if(vis[a[i]]==0){g2++;vis[a[i]]=1;}
            else{ff=0;break;}
            if(g2==maxx){g2=i;break;}
        }
        //cout<<ge<<g2<<endl;
        if(!f && !ff){printf("0\n");}
        else{

            if(f){
                int zhi=n-ge;
                for(it i=1;i<=zhi;i++){vis[i]=0;}
                for(it i=ge+1;i<=n;i++){
                    vis[a[i]]++;
                }
                for(it i=1;i<=zhi;i++){
                    if(vis[i]==0){f=0;break;}
                }
            }
            if(ff){
                int zhi=g2;
                for(it i=1;i<zhi;i++){vis[i]=0;}
                for(it i=1;i<zhi;i++){
                    vis[a[i]]++;
                }
                for(it i=1;i<zhi;i++){
                    if(vis[i]==0){ff=0;break;}
                }
            }
            if(!f && !ff){printf("0\n");}
            else{
                if(ff && f){
                    if(ge==g2-1){
                         printf("1\n%d %d\n",ge,n-ge);
                    }
                    else{
                        printf("2\n%d %d\n%d %d\n",ge,n-ge,g2-1,n-g2+1);
                    }
                }
                else if(f){
                    printf("1\n%d %d\n",ge,n-ge);
                }
                else{
                    printf("1\n%d %d\n",g2-1,n-g2+1);
                }
            }
        }
    }
    return 0;
}

 

 

D题

题意:

You are given two integers d,md,m, find the number of arrays aa, satisfying the following constraints:

  • The length of aa is nn, n1n≥1
  • 1a1<a2<<and1≤a1<a2<⋯<an≤d
  • Define an array bb of length nn as follows: b1=a1b1=a1, i>1,bi=bi1ai∀i>1,bi=bi−1⊕ai, where ⊕ is the bitwise exclusive-or (xor). After constructing an array bb, the constraint b1<b2<<bn1<bnb1<b2<⋯<bn−1<bn should hold.

Since the number of possible arrays may be too large, you need to find the answer modulo mm.

看条件就了解,找到符合的种类

思路:

因为是位运算,我一开始想的是二进制,然后1,2,4,8的找规律,样例给了规律

就是1(二进制一位),转换成2 (二进制两位)的时候是+2,2转换4(二进制三位)的是+6,4转换位8(二进制四位)的是+30

1  2  3   4   5   6    7     8    9

1  3  5  11 17  23  29   59   89  

  2  2  6   6   6     6    30    30

刚好是4前面3的数据+1,8前面7的数据+1,比赛的时候脑瘫,不相信这规律,特地验证了一波,为什么是+1,举个例子8为什么是加30,因为会出现1 8这种数据,其他29就是前者数据后面都加个8(别问为什么举例的是8,呜呜呜)

证明完以后就十分钟写,因为数据10^9,所以要存二进制,分别用a存二进制位数时候要+多少,b存二进制位数前一个数据量是多少。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define pii pair<int,int>
#define mak(n,m) make_pair(n,m)
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
const int maxn=1e5+10;
ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}
int t;
ll n,m;
ll a[40],b[40];
int main(){
  
    scanf("%d",&t);
    while(t--){
        scanf("%lld%lld",&n,&m);
        if(n==1){printf("%d\n",n%m);continue;}
        ll k=n;
        ll c=0;
        while(k){
            if(k==0){break;}
            c++;k>>=1;
        }
          a[0]=1,a[1]=2;b[0]=1;b[1]=1;
        for(ll i=2;i<=c;i++){
            ll c=(ll)1<<i,c1=(ll)1<<(i-1);
            b[i]=((c-c1)%m*a[i-1]%m+b[i-1])%m;
            a[i]=(b[i]+1)%m;
        }
   // cout<<a[5]<<a[3]<<a[4]<<endl;
    //cout<<b[2]<<b[3]<<b[4]<<endl;
        printf("%lld\n",(b[c-1]%m+((n+1-(1<<(c-1)))*a[c-1])%m)%m);
    }
    return 0;
}

有1说1,十二分钟搓出来,都没来得及交上去。呜呜呜迷惑C题,

posted @ 2020-04-04 10:56  ouluy  阅读(293)  评论(0编辑  收藏  举报