题目链接
题意:
给 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
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;
}
}
题意:
给 一 个 长 度 为 n 的 数 组 给一个长度为n的数组 给一个长度为n的数组
是 否 能 分 成 左 右 两 部 分 , 使 得 每 部 分 成 为 一 个 序 列 是否能分成左右两部分,使得每部分成为一个序列 是否能分成左右两部分,使得每部分成为一个序列
即 包 含 1 − x 的 所 有 数 即包含1-x的所有数 即包含1−x的所有数
题解:
直 接 计 算 前 缀 和 和 后 缀 和 直接计算前缀和和后缀和 直接计算前缀和和后缀和
用 一 个 m a p 存 一 下 是 否 出 现 重 复 元 素 , 出 现 就 b r e a k 用一个map存一下是否出现重复元素,出现就break 用一个map存一下是否出现重复元素,出现就break
否 则 用 高 斯 公 式 算 如 果 前 缀 和 和 后 缀 和 都 满 足 则 记 录 答 案 否则用高斯公式算 如果前缀和和后缀和都满足则记录答案 否则用高斯公式算如果前缀和和后缀和都满足则记录答案
AC代码
#include
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;
}
}
}
题意:
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
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 和 m , m 是 模 数 , 最 后 答 案 向 m 取 余 给一个数d和m,m是模数,最后答案向m取余 给一个数d和m,m是模数,最后答案向m取余
让 你 构 造 一 个 数 组 1 < = a 1 < a 2 < . . . . a n < = d 让你构造一个数组1<=a_1
必 须 存 在 数 组 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从0开始,假设最高位是1<<i,存在2i种数
所 以 每 次 用 前 面 的 所 有 情 况 乘 这 个 数 的 种 类 数 所以每次用前面的所有情况乘这个数的种类数 所以每次用前面的所有情况乘这个数的种类数
并 且 加 上 这 个 数 单 独 存 在 的 情 况 , 然 后 加 上 前 面 所 有 出 现 的 情 况 并且加上这个数单独存在的情况,然后加上前面所有出现的情况 并且加上这个数单独存在的情况,然后加上前面所有出现的情况
这 样 就 构 造 出 了 一 个 O ( l o g 2 d ) 复 杂 度 的 d p 操 作 这样就构造出了一个O(log_2d)复杂度的dp操作 这样就构造出了一个O(log2d)复杂度的dp操作
由 于 每 次 操 作 只 和 前 一 个 有 关 , 所 以 只 用 一 个 数 一 直 维 护 就 可 以 由于每次操作只和前一个有关,所以只用一个数一直维护就可以 由于每次操作只和前一个有关,所以只用一个数一直维护就可以
AC代码
#include
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;
}