牛客练习赛100
作者:互联网
牛客练习赛100
https://ac.nowcoder.com/acm/contest/11251
简要地写一下 A-E 的解答。
A-D 为了减少篇幅没有放头文件等东西,可以到 E 题去取。
A
范围不大,直接枚举来找即可。
int main(){
int a, b, n; cin>>a>>b>>n;
for(int i=0; ; i++){
int t=n-a*i;
if(t<0) break;
if(t%b==0) return cout<<i<<' '<<t/b, 0;
}
puts("-1");
return 0;
}
B
考虑 dp。
\(f(i, j, k)\) 表示前 \(i\) 个元素,最后一个元素决策种类为 \(j, k\) 的最大贡献。
const int N=2e5+50;
int n;
int w[N];
string s;
int f[N][2][2];
signed main(){
cin>>n;
rep(i,1,n) read(w[i]);
cin>>s;
s=" "+s;
memset(f, 0xcf, sizeof f);
rep(i,0,1) rep(j,0,1) f[0][i][j]=0;
int res=0;
rep(i,1,n) rep(j,0,1) rep(k,0,1){
f[i][j][k]=f[i-1][j][k];
if(j==(w[i]&1) && k==(s[i]=='B')) f[i][j][k]=max(f[i][j][k], f[i-1][j^1][k^1]+w[i]);
res=max(res, f[i][j][k]);
}
cout<<res;
return 0;
}
C
首先排除所有字符 \(0\)。
将剩下的字符按照 \(mod~3\) 的结果分类为 \(0, 1, 2\),存入桶(cnt
)中。
然后小红先取一个(当然如果没得取那就直接小红输了)。
发现小紫只能从 cnt[1], cnt[2]
中取,而取完之后小红只能相应地从另一个桶中取,所以整个过程两个人会将 cnt[1], cnt[2]
至少一个取完。
- 如果
cnt[1], cnt[2]
不相等,那当二人取完cnt[1], cnt[2]
至少一个的时候小紫取还有剩的那个桶即可胜利。 - 如果相等,那么就判断
cnt[0]
是否为 \(0\),如果不为 \(0\) 代表小紫无法进行最后一步而失败,否则胜利。
int main(){
string s; cin>>s;
vector<int> cnt(3);
for(auto i: s) if(i!='0'){
int val=(i-'0')%3;
cnt[val]++;
}
int x=((cnt[1]+cnt[2]*2)%3)%3;
if(!cnt[x]) return puts("yukari"), 0;
cnt[x]--;
if(cnt[1]!=cnt[2]) return puts("yukari"), 0;
puts(cnt[0]==0? "yukari": "kou");
return 0;
}
D
考虑一开始就安排 \(66666\) 组 re
。
注意到在第 \(k\) 组后插入 \(x\) 个 d
时,会产生 \(x\times k(k+1)/2\) 的贡献,所以根据试填法的思想,考虑从组数大的向小的方向插入 d
即可。
#define int long long
signed main(){
const int tot=66666;
int n; cin>>n;
if(!n) return puts("re"), 0;
vector<int> b(tot+1);
for(int i=tot; i; i--){
int t=i*(i+1)/2;
b[i]+=n/t, n%=t;
}
for(int i=1; i<=tot; i++){
cout<<"re";
while(b[i]--) cout<<"d";
}
return 0;
}
E
珂朵莉树。
因为数据随机而且区间不会分裂,复杂度是正确的。
但是实现时珂朵莉树的值 v
尽量不要用 map
(存质因子和相应的个数),实测慢的飞起。
// Problem: 小红的公倍数
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11251/E
// Memory Limit: 1048576 MB
// Time Limit: 6000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define int long long
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
#define IT set<node>::iterator
const int N=20020;
int p[N], cnt;
bool vis[N];
void sieve(int n){
for(int i=2; i<=n; i++){
if(!vis[i]) p[++cnt]=i;
for(int j=1; p[j]*i<=n; j++){
vis[p[j]*i]=true;
if(i%p[j]==0) break;
}
}
}
struct node{
int l,r;
mutable vector<pii> v;
node(int L,int R=-1, vector<pii> V={}):l(L),r(R),v(V){};//构造函数
bool operator<(const node&o)const{//运算符重载
return l<o.l;
}
};
set<node>s;
//分裂
IT split(int p){
IT it=s.lower_bound(node(p));
if(it->l==p) return it; //如果p在it对应的区间里面
it--; //否则找上一个it(p必然在相应区间上)
//模拟分裂区间
int L=it->l; int R=it->r; vector<pii> V=it->v;
s.erase(it);
s.insert(node(L,p-1,V));
return s.insert(node(p,R,V)).first; //insert会返回一个pair类型 first是迭代器 second是bool类型
}
//推平
void assign(int l,int r, vector<pii> v){
IT itr=split(r+1); IT itl=split(l);
s.erase(itl,itr);
s.insert(node(l,r,v));
}
void merge(vector<pii> &a, vector<pii> &b){
vector<int> buf(20020);
for(auto &[x, y]: a) buf[x]=y;
for(auto &[x, y]: b) buf[x]=max(buf[x], y);
a.clear();
rep(i,1,cnt) if(buf[p[i]]) a.pb({p[i], buf[p[i]]});
// for(auto &[x, y]: res) a.pb({x, y});
}
vector<pii> query(int l, int r){
IT itr=split(r+1); IT itl=split(l);
vector<pii> res;
for(; itl!=itr; itl++){
merge(res, itl->v);
}
return res;
}
int n, q;
vector<pii> get(int x){
vector<pii> res;
for(int i=2; i<=x/i; i++){
if(x%i==0){
int cnt=0;
while(x%i==0) x/=i, cnt++;
res.pb({i, cnt});
}
}
if(x>1) res.pb({x, 1});
return res;
}
const int mod=1e9+7;
int fpow(int x, int p){
int res=1;
for(; p; p>>=1, x=x*x%mod) if(p&1) res=res*x%mod;
return res%mod;
}
int get(vector<pii> mp){
int res=1;
for(auto &[x, y]: mp) (res*=fpow(x, y))%=mod;
return res;
}
signed main(){
sieve(N-20);
cin>>n>>q;
rep(i,1,n){
int x; read(x);
s.insert(node(i, i, get(x)));
}
while(q--){
int l, r; read(l), read(r);
auto val=query(l, r);
cout<<get(val)<<endl;
assign(l, r, val);
}
return 0;
}
标签:cnt,练习赛,return,int,res,rep,牛客,vector,100 来源: https://www.cnblogs.com/Tenshi/p/16367241.html