A.Dreamoon and Ranking Collection
题意:
给
n
个
数
,
是
否
存
在
一
个
1
−
v
的
序
列
给n个数,是否存在一个1-v的序列
给n个数,是否存在一个1−v的序列
其
中
如
果
某
个
数
不
存
在
,
可
以
跳
过
x
次
其中如果某个数不存在,可以跳过x次
其中如果某个数不存在,可以跳过x次
找
出
最
大
的
v
找出最大的v
找出最大的v
题解:
用
数
组
存
一
下
每
个
数
的
个
数
用数组存一下每个数的个数
用数组存一下每个数的个数
从
1
−
200
循
环
,
如
果
数
存
在
就
下
一
个
,
不
存
在
就
跳
过
从1-200循环,如果数存在就下一个,不存在就跳过
从1−200循环,如果数存在就下一个,不存在就跳过
直
到
x
=
=
0
&
&
当
前
数
不
存
在
直到x==0~\&\&~当前数不存在
直到x==0 && 当前数不存在
AC代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int a[210],b[210];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
cin>>t;
while(t--){
int n,x,ans=0;
cin>>n>>x;
memset(b,0,sizeof b);
for(int i=1;i<=n;i++)cin>>a[i],b[a[i]]=1;
for(int i=1;i<=200;i++){
if(!b[i]&&!x)break;
if(!b[i])x--;
ans=i;
}
cout<<ans<<endl;
}
}
B.Dreamoon Likes Permutations
题意:
给
一
个
长
度
为
n
的
数
组
给一个长度为n的数组
给一个长度为n的数组
是
否
能
分
成
左
右
两
部
分
,
使
得
每
部
分
成
为
一
个
序
列
是否能分成左右两部分,使得每部分成为一个序列
是否能分成左右两部分,使得每部分成为一个序列
即
包
含
1
−
x
的
所
有
数
即包含1-x的所有数
即包含1−x的所有数
题解:
直
接
计
算
前
缀
和
和
后
缀
和
直接计算前缀和和后缀和
直接计算前缀和和后缀和
用
一
个
m
a
p
存
一
下
是
否
出
现
重
复
元
素
,
出
现
就
b
r
e
a
k
用一个map存一下是否出现重复元素,出现就break
用一个map存一下是否出现重复元素,出现就break
否
则
用
高
斯
公
式
算
如
果
前
缀
和
和
后
缀
和
都
满
足
则
记
录
答
案
否则用高斯公式算 如果前缀和和后缀和都满足则记录答案
否则用高斯公式算如果前缀和和后缀和都满足则记录答案
AC代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
cin>>t;
while(t--){
int n;
vector<int> ans;
map<int,int> m1,m2;
cin>>n;
int num=0;
ll pre=0,sum=0;
for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i],m2[a[i]]++;
for(ll i=1;i<n;i++){
pre+=a[i];
m1[a[i]]++;
if(m1[a[i]]>1) break;
m2[a[i]]--;
if(m2[a[i]]==0) m2.erase(a[i]);
if(m1.size()+m2.size()==n&&pre==(1+i)*i/2&&(sum-pre)==(1+n-i)*(n-i)/2) ans.pb(i),num++;
}
cout<<ans.size()<<endl;
for(auto i:ans){
cout<<i<<' '<<n-i<<endl;
}
}
}
C.Dreamoon Likes Coloring
题意:
n
个
点
,
涂
色
m
次
,
每
次
涂
的
长
度
为
L
i
,
颜
色
为
i
n个点,涂色m次,每次涂的长度为L_i,颜色为i
n个点,涂色m次,每次涂的长度为Li,颜色为i
你
选
定
的
涂
色
位
置
必
须
保
证
整
个
长
度
都
能
够
涂
上
该
颜
色
你选定的涂色位置必须保证整个长度都能够涂上该颜色
你选定的涂色位置必须保证整个长度都能够涂上该颜色
每
个
点
的
颜
色
取
决
于
最
后
一
次
涂
的
颜
色
每个点的颜色取决于最后一次涂的颜色
每个点的颜色取决于最后一次涂的颜色
确
保
每
个
颜
色
都
存
在
并
且
每
个
点
都
有
颜
色
确保每个颜色都存在并且每个点都有颜色
确保每个颜色都存在并且每个点都有颜色
题解:
特
判
一
下
颜
色
不
覆
盖
,
如
果
不
够
n
个
点
,
输
出
−
1
特判一下颜色不覆盖,如果不够n个点,输出-1
特判一下颜色不覆盖,如果不够n个点,输出−1
然
后
如
果
还
没
涂
的
长
度
能
够
大
于
没
涂
的
点
,
就
在
上
次
涂
后
的
下
一
个
点
涂
然后如果还没涂的长度能够大于没涂的点,就在上次涂后的下一个点涂
然后如果还没涂的长度能够大于没涂的点,就在上次涂后的下一个点涂
如
果
这
样
涂
超
出
了
n
个
点
,
就
输
出
−
1
如果这样涂超出了n个点,就输出-1
如果这样涂超出了n个点,就输出−1
如
果
剩
余
还
没
涂
的
长
度
小
于
剩
下
的
点
,
就
在
n
−
s
u
m
i
+
1
位
置
开
始
涂
如果剩余还没涂的长度小于剩下的点,就在n-sum_i+1位置开始涂
如果剩余还没涂的长度小于剩下的点,就在n−sumi+1位置开始涂
AC代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
ll l[maxn],sum[maxn],ans[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>l[i];
for(int i=m;i;--i)
sum[i]=sum[i+1]+l[i];
if(sum[1]<n){cout<<-1;return 0;}
ans[1]=1;
for(int i=2;i<=m;++i)
ans[i]=max(ans[i-1]+1,n-sum[i]+1);
for(int i=1;i<=m;++i)if(ans[i]+l[i]-1>n){cout<<-1;return 0;}
for(int i=1;i<=m;++i)
cout<<ans[i]<<' ';
return 0;
}
D.Dreamoon Likes Sequences
题意:
给
一
个
数
d
和
m
,
m
是
模
数
,
最
后
答
案
向
m
取
余
给一个数d和m,m是模数,最后答案向m取余
给一个数d和m,m是模数,最后答案向m取余
让
你
构
造
一
个
数
组
1
<
=
a
1
<
a
2
<
.
.
.
.
a
n
<
=
d
让你构造一个数组1<=a_1<a_2<....a_n<=d
让你构造一个数组1<=a1<a2<....an<=d
必
须
存
在
数
组
b
是
a
的
异
或
前
缀
,
保
证
b
也
是
严
格
升
序
必须存在数组b是a的异或前缀,保证b也是严格升序
必须存在数组b是a的异或前缀,保证b也是严格升序
题解:
可
以
看
出
,
如
果
b
也
是
严
格
升
序
的
话
可以看出,如果b也是严格升序的话
可以看出,如果b也是严格升序的话
必
须
让
a
的
每
一
位
数
的
二
进
制
最
高
位
大
于
前
一
位
的
最
高
位
必须让a的每一位数的二进制最高位大于前一位的最高位
必须让a的每一位数的二进制最高位大于前一位的最高位
所
以
就
对
每
一
二
进
制
位
循
环
所以就对每一二进制位循环
所以就对每一二进制位循环
i
从
0
开
始
,
假
设
最
高
位
是
1
<
<
i
,
存
在
2
i
种
数
i从0开始,假设最高位是1<<i,存在2^i种数
i从0开始,假设最高位是1<<i,存在2i种数
所
以
每
次
用
前
面
的
所
有
情
况
乘
这
个
数
的
种
类
数
所以每次用前面的所有情况乘这个数的种类数
所以每次用前面的所有情况乘这个数的种类数
并
且
加
上
这
个
数
单
独
存
在
的
情
况
,
然
后
加
上
前
面
所
有
出
现
的
情
况
并且加上这个数单独存在的情况,然后加上前面所有出现的情况
并且加上这个数单独存在的情况,然后加上前面所有出现的情况
这
样
就
构
造
出
了
一
个
O
(
l
o
g
2
d
)
复
杂
度
的
d
p
操
作
这样就构造出了一个O(log_2d)复杂度的dp操作
这样就构造出了一个O(log2d)复杂度的dp操作
由
于
每
次
操
作
只
和
前
一
个
有
关
,
所
以
只
用
一
个
数
一
直
维
护
就
可
以
由于每次操作只和前一个有关,所以只用一个数一直维护就可以
由于每次操作只和前一个有关,所以只用一个数一直维护就可以
AC代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
//const int mod=1e9+7;
const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=2e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
cin>>t;
while(t--){
ll d,m;
cin>>d>>m;
ll ans=0;
for(int i=0;(1ll<<i)<=d;i++){
int s=0;
if((1ll<<(i+1))<=d)s=1<<i;
else s=d-(1<<i)+1;
ans=(ans+s*ans%m+s)%m;
}
cout<<ans<<endl;
}
return 0;
}