Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!

A题

题意:

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

思路:

模拟就行

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define il inline
 6 #define it register int
 7 #define inf 0x3f3f3f3f
 8 #define lowbit(x) (x)&(-x)
 9 #define pii pair<int,int>
10 #define mak(n,m) make_pair(n,m)
11 #define mem(a,b) memset(a,b,sizeof(a))
12 #define mod 998244353
13 #define fi first
14 #define se second
15 #define sz(x) (int)(x).size()
16 #define all(x) (x).begin(), (x).end()
17 const int maxn=1e3+10;
18 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;}
19 int t,n,m;
20 int v[maxn];
21 int main(){
22     scanf("%d",&t);
23     while(t--){
24         scanf("%d%d",&n,&m);
25         int a;mem(v,0);
26         for(it i=0;i<n;i++){
27             scanf("%d",&a);v[a]=1;
28         }
29         int maxx=0;
30         for(it i=1;m;i++){
31             if(v[i]==0){v[i]=1;m--;maxx=i;}
32             else{maxx=i;}
33         }
34         for(it i=maxx+1;;i++){
35             if(v[i]){maxx=i;}
36             else{break;}
37         }
38         printf("%d\n",maxx);
39     }
40     return 0;
41 }

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

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define il inline
 6 #define it register int
 7 #define inf 0x3f3f3f3f
 8 #define lowbit(x) (x)&(-x)
 9 #define pii pair<int,int>
10 #define mak(n,m) make_pair(n,m)
11 #define mem(a,b) memset(a,b,sizeof(a))
12 #define mod 998244353
13 #define fi first
14 #define se second
15 #define sz(x) (int)(x).size()
16 #define all(x) (x).begin(), (x).end()
17 const int maxn=2e5+10;
18 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;}
19 int t,n,m;
20 int a[maxn],vis[maxn];
21 int main(){
22     scanf("%d",&t);
23     while(t--){
24         scanf("%d",&n);
25         mem(vis,0);int f=1,maxx=-1;
26         for(it i=1;i<=n;i++){
27             scanf("%d",&a[i]);
28             //vis[a[i]]++;
29             if(maxx<a[i]){maxx=a[i];}
30         }
31         int ge=0;
32         for(it i=1;i<=n;i++){
33             if(vis[a[i]]==0){ge++;vis[a[i]]=1;}
34             else{f=0;break;}
35             if(ge==maxx){ge=i;break;}
36         }
37         int ff=2,g2=0;mem(vis,0);
38         for(it i=n;i>=1;i--){
39             if(vis[a[i]]==0){g2++;vis[a[i]]=1;}
40             else{ff=0;break;}
41             if(g2==maxx){g2=i;break;}
42         }
43         //cout<<ge<<g2<<endl;
44         if(!f && !ff){printf("0\n");}
45         else{
46
47             if(f){
48                 int zhi=n-ge;
49                 for(it i=1;i<=zhi;i++){vis[i]=0;}
50                 for(it i=ge+1;i<=n;i++){
51                     vis[a[i]]++;
52                 }
53                 for(it i=1;i<=zhi;i++){
54                     if(vis[i]==0){f=0;break;}
55                 }
56             }
57             if(ff){
58                 int zhi=g2;
59                 for(it i=1;i<zhi;i++){vis[i]=0;}
60                 for(it i=1;i<zhi;i++){
61                     vis[a[i]]++;
62                 }
63                 for(it i=1;i<zhi;i++){
64                     if(vis[i]==0){ff=0;break;}
65                 }
66             }
67             if(!f && !ff){printf("0\n");}
68             else{
69                 if(ff && f){
70                     if(ge==g2-1){
71                          printf("1\n%d %d\n",ge,n-ge);
72                     }
73                     else{
74                         printf("2\n%d %d\n%d %d\n",ge,n-ge,g2-1,n-g2+1);
75                     }
76                 }
77                 else if(f){
78                     printf("1\n%d %d\n",ge,n-ge);
79                 }
80                 else{
81                     printf("1\n%d %d\n",g2-1,n-g2+1);
82                 }
83             }
84         }
85     }
86     return 0;
87 }

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, n≥1n≥1
  • 1≤a1<a2<?<an≤d1≤a1<a2<?<an≤d
  • Define an array bb of length nn as follows: b1=a1b1=a1, ∀i>1,bi=bi−1⊕ai∀i>1,bi=bi−1⊕ai, where ⊕⊕ is the bitwise exclusive-or (xor). After constructing an array bb, the constraint b1<b2<?<bn−1<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题,

原文地址:https://www.cnblogs.com/luoyugongxi/p/12630768.html

时间: 2024-08-03 10:57:11

Codeforces Round #631 (Div. 2) - Thanks, Denis aramis Shitov!的相关文章

Codeforces Round #631 (Div. 2)

A 用桶维护即可 #include <bits/stdc++.h> using namespace std; const int N = 205; int t,n,x,a[N],b[N]; signed main() { ios::sync_with_stdio(false); cin>>t; while(t--) { cin>>n>>x; for(int i=1;i<=n;i++) cin>>a[i]; memset(b,0,sizeof

Codeforces Round #631 (Div. 2) D.Dreamoon Likes Sequences

题目连接:Dreamoon Likes Sequences  题意:给你d和m,让你构造一个递增数组a,使数组b(i==1,b[i]=a[i] ; i>1, b[i]=b[i-1]^a[i])递增,求a有几种,答案模m. 题解:根据异或的性质可以得出:2后边不能有3, 4后边不能有5~7, 8后边不能有9~15...... 然后就很好写了.用数组b记录第i个数可以取得数有多少个,数组dp记录长度为 i 的 a 数组有几种.看下边的代码应该就清楚了. 1 #include<bits/stdc++

Codeforces Round #631 (Div. 2) Dreamoon Likes Sequences

题面很短,别的博客也讲了就不说题意了. 做法: 异或是没有进位的加法,所以ai + 1的二进制最高位要大于ai的二进制最高位,才能满足ai递增,bi也递增的条件.呐这样的话,选了4,(5,6,7)就都不能选了,只能选比7大的数. 这样分析下来a数组最长也只有30,(2^30>1e9) 直接按照数字大小dp会TLE 思路角度1:换一个角度,我们把二进制最高位相同的看作一组,因为这一组内只能选一个数. 有点像分组背包.但是我们现在只看分组背包的方案数,所以就不用枚举每一组内的物品了. dpij表示考

Codeforces Round #631 (Div. 2) B. Dreamoon Likes Permutations(排列组合)

The sequence of mm integers is called the permutation if it contains all integers from 11 to mm exactly once. The number mm is called the length of the permutation. Dreamoon has two permutations p1p1 and p2p2 of non-zero lengths l1l1 and l2l2 . Now D

Codeforces Round #631 (Div. 2) C. Dreamoon Likes Coloring(贪心好题/意识流题解)

Dreamoon likes coloring cells very much. There is a row of nn cells. Initially, all cells are empty (don't contain any color). Cells are numbered from 11 to nn . You are given an integer mm and mm integers l1,l2,…,lml1,l2,…,lm (1≤li≤n1≤li≤n ) Dreamoo

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #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

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd