其他分享
首页 > 其他分享> > 牛客练习赛100

牛客练习赛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] 至少一个取完。

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