Codeforces Round #829#830
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #829#830相关的知识,希望对你有一定的参考价值。
D1. Balance (Easy version)
思路:刚开始使用set查找元素超时了。之后想到我只要判断出元素在不在几何中就好,由于数组需要离散化,所以开map记录。
mp:记录元素是否出现在集合中;
a:记录该元素对应的最小倍数,及时用while暴力更新
#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
char c;int x;
map<int,int>mp,a;
void solve()
mp[0]=1;
int q;cin>>q;
while(q--)
cin>>c>>x;
if(c=='+')
mp[x]=1;
else
int tmp=a[x];
while(mp[tmp]) tmp+=x;
a[x]=tmp;
cout<<tmp<<endl;
signed main()
ios;
//int T;cin>>T;
//while(T--)
solve();
return 0;
//int fac[N],inv[N];
//int qpow(int a,int b)
// int res=1;
// while(b)
//
// if(b&1) res=res*a%mod;
// a=a*a%mod;
// b>>=1;
//
// return res;
//
//int getinv(int x)return qpow(x,mod-2);
//int C(int a,int b)
//
// return (fac[a]*inv[a-b]%mod)*inv[b]%mod;
//
C1. Make Nonzero Sum (easy version)
这题做的时候是真的么思路,觉得情况很复杂,区间的大小不好控制,正负1的也会随着位置而改变作用。知道后来,队友的出现……把我讲懂了。当时讲到每个数作为一个区间的情况,怎么就不往下再想想……
思路:
1.通常情况下,正负1的个数相等,每个数作为一个区间,肯定可以约掉。若正负1的数量加起来是个奇数,此情况无解。
2.此外若出现连续个1,则第二个1、第四个1……可转化为-1看待,两两为一组区间,直到正1和负1的数量相等。
3.若出现连续个-1,情况与2类似。
#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,a[N];
bool vis[N];
vector<pair<int,int>>e;
void solve()
e.clear();
cin>>n;
for(int i=0;i<=n+5;i++) vis[i]=0;
int num1=0,num2=0;
for(int i=1;i<=n;i++)
cin>>a[i];
if(a[i]==1) num1++;
else if(a[i]==-1) num2++;
if((num1+num2)%2!=0)
cout<<-1<<endl;return;
if(num1==num2)
for(int i=1;i<=n;i++) e.push_back(i,i);
else if(num1>num2)
for(int i=1;i<n&&num1>num2;i++)
if(a[i]==1&&a[i+1]==1)
e.push_back(i,i+1);num1--;num2++;
vis[i]=vis[i+1]=1;
i++;
for(int i=1;i<=n;i++)
if(!vis[i]) e.push_back(i,i);
else
for(int i=1;i<n&&num1<num2;i++)
if(a[i]==-1&&a[i+1]==-1)
e.push_back(i,i+1);num2--;num1++;
vis[i]=vis[i+1]=1;
i++;
for(int i=1;i<=n;i++)
if(!vis[i]) e.push_back(i,i);
cout<<e.size()<<endl;
sort(e.begin(),e.end(),[&](pair<int,int> &p,pair<int,int> &q)
return p.first<q.first;
);
for(auto x:e)
cout<<x.first<<" "<<x.second<<endl;
signed main()
//ios;
int T;cin>>T;
while(T--)
solve();
return 0;
C2. Make Nonzero Sum (hard version)
思路:
1.在C1的基础上,引入了0,可分析出,在大方向正1和负1相等时,又多出两种情况。
2.0后面跟着1,可看作为-1。0后面跟着-1,可看作1.
#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,a[N];
bool vis[N];
vector<pair<int,int>>e;
void solve()
e.clear();
cin>>n;
for(int i=0;i<=n+5;i++) vis[i]=0;
int num1=0,num2=0;
for(int i=1;i<=n;i++)
cin>>a[i];
if(a[i]==1) num1++;
else if(a[i]==-1) num2++;
if((num1+num2)%2!=0)
cout<<-1<<endl;return;
if(num1==num2)
for(int i=1;i<=n;i++) e.push_back(i,i);
else if(num1>num2)
for(int i=1;i<n&&num1>num2;i++)
if((a[i]==1&&a[i+1]==1)||(a[i]==0&&a[i+1]==1))
e.push_back(i,i+1);num1--;num2++;
vis[i]=vis[i+1]=1;
i++;
for(int i=1;i<=n;i++)
if(!vis[i]) e.push_back(i,i);
else
for(int i=1;i<n&&num1<num2;i++)
if((a[i]==-1&&a[i+1]==-1)||(a[i]==0&&a[i+1]==-1))
e.push_back(i,i+1);num2--;num1++;
vis[i]=vis[i+1]=1;
i++;
for(int i=1;i<=n;i++)
if(!vis[i]) e.push_back(i,i);
cout<<e.size()<<endl;
sort(e.begin(),e.end(),[&](pair<int,int> &p,pair<int,int> &q)
return p.first<q.first;
);
for(auto x:e)
cout<<x.first<<" "<<x.second<<endl;
signed main()
//ios;
int T;cin>>T;
while(T--)
solve();
return 0;
C1. Sheikh (Easy version)
分析:这题写代码写的很差,出现了好几个小错误,都没看出来。
1.关键点:从1开始,每多出一个数值,f的值肯定是递增的,因此最大值肯定为f[n]时。
2.存在不从1开始的起点,长度为len,其值也为f[n]。
#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,q,a[N],mx,ll,rr;
int sum[N],xr[N];
bool check(int x)
int res=0;
for(int i=x;i<=n;i++)
int tmp=sum[i]-sum[i-x]-(xr[i]^xr[i-x]);
if(res<=tmp)
res=tmp;ll=i-x+1,rr=i;
if(res>=mx)
return 1;
else return 0;
void solve()
cin>>n>>q;
for(int i=0;i<=n+5;i++) sum[i]=a[i]=xr[i]=0;
ll=rr=mx=0;
for(int i=1;i<=n;i++)
cin>>a[i];
sum[i]=sum[i-1]+a[i];
xr[i]=xr[i-1]^a[i];
int p,q;cin>>p>>q;
mx=sum[n]-xr[n];
// for(int i=1;i<=n;i++)
//
// cout<<sum[i]<<" "<<xor[i]<<" "<<f[i]<<endl;
//
int l=1,r=n,mid,ans;
while(l<=r)
mid=(l+r)>>1;
if(check(mid))
r=mid-1,ans=mid;
else
l=mid+1;
check(ans);
cout<<ll<<" "<<rr<<endl;
signed main()
ios;
int T;cin>>T;
while(T--)
solve();
return 0;以上是关于Codeforces Round #829#830的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #829 Div. 2 D. Factorial Divisibility(结论&数学)
Codeforces 830D Singer House - 动态规划