竞赛讨论区 > 【题解】2022牛客寒假算法基础集训营2
头像
沙烬
编辑于 2022-01-30 00:13
+ 关注

【题解】2022牛客寒假算法基础集训营2

补题可以看这里
可能有些有我自己的一些宏定义,会显得比较长,大家可以直接看solve部分即可。
K 签到 模拟
#include<iostream>
using namespace std;
int cnt[10];
int main(){
    string s;cin>>s;
    for(char ch:s)if(ch!='5')cnt[ch-'0']++,cnt[5]++;
    for(int i=1;i<=9;i++)cout<<cnt[i]<<" ";
}


C 模拟 贪心
#include<iostream>
using namespace std;
int main(){
    long long x,a,b;cin>>x>>a>>b;
    string s;cin>>s;
    int len=0;
    for(char ch:s)
        if(ch=='1'&&x>=a)len++,x-=a;
        else x+=b;
    cout<<len;
}



E 欧拉图
#include<iostream>
using namespace std;
typedef long long ll;
int main(){
    ll n;cin>>n;
    if(n&1)cout<<n-1<<" "<<n*(n-1)/2<<"\n";
    else cout<<n-1<<" "<<n*(n-1)/2-n/2+1<<"\n";
}



H 简单数学
#include<iostream>
using namespace std;
const int mod=1e9+7;
int main(){
    long long n,m;
    cin>>n>>m;
    n%=mod;
    long long ans=1;
    while(m){
        if(m%2==1)ans=ans*n%mod;
        m/=2;
    }
    cout<<ans;
}


A 推结论
这里放jls的写法~
#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, k;
    cin >> n >> m >> k;
    n = std::min(n, m + 1);
    for (int i = 0; i < k; i++) {
        long long x;
        cin >> x;
        long long s = std::sqrt(x);
        if (s > n) {
            s = n;
        }
        if (s * (2 * m + s + 1) / 2 >= x) 
            cout << "YES\n";
        else 
            cout << "NO\n";
    }
}


I 构造
#include<bits/stdc++.h>
using namespace std;
char ans[10010];
set<char>ft;
int m,n;
char *s="<\\[{(!'*+-.08:=^_WTYUIOAHXVM|\"",*t=">/]})!'*+-.08:=^_WTYUIOAHXVM|\"";
int main(){
	cin>>n>>m;
	if(m==1)while(n--)putchar(34);
	else{
		if(n&1)ans[n+1>>1]=34,ft.insert(34);
		for(int i=1,ii=n,j=n/2,k=0;j;++i,--ii,--j){
			if(ft.size()+1==m)k=max(k,5);
			ans[i]=s[k],ans[ii]=t[k];
			ft.insert(s[k]),ft.insert(t[k]);
			if(ft.size()<m)++k;
			k%=30;
		}
		puts(ft.size()!=m?"-1":ans+1);
	}
}


F 逆元
#include <bits/stdc++.h>
using namespace std;
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);
typedef long long ll;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const double eps=1e-6;
const double PI=acos(-1.0);
inline ll read()
{
	char ch;ll x=0;bool f=true;
	for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f^=f;
	for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
	return f?x:-x;
}
const int N=1e6+7;
const int mod=1e9+7;
int f[N];
ll s[N],ac[N],res=0;
ll ksm(ll n,ll m){
    ll sum=1;
    while(n){
        if(n&1)sum=sum*m%mod;
        m=m*m%mod;
        n>>=1;
    }
    return sum;
}
ll inv(ll m){
    return ksm(mod-2,m);
}
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
void solve(){
    int n=read(),q=read();
    string str;cin>>str;str=" "+str;
    for(int i=1;i<=n;i++)f[i]=i,ac[i]=s[i]=read(),assert(0<s[i]&&s[i]<mod);
    for(int i=1;i<n;i++)if(str[i]=='*'){
        int fa=find(i),fb=find(i+1);
        f[fa]=fb;
        s[fb]=s[fb]*s[fa]%mod;
    }
    for(int i=1;i<=n;i++)
        if(find(i)==i)
            res=(res+s[i])%mod;
    while(q--){
        ll x=read(),y=read();
        assert(x<=n);
        ll fa=find(x);
        res=(res-s[fa]+mod)%mod;
        s[fa]=s[fa]*inv(ac[x])%mod;
        ac[x]=y;
        s[fa]=s[fa]*y%mod;
        res=(res+s[fa])%mod;
        cout<<res<<"\n";
    }
}
int main()
{
    //fre("5");
	int T=1;
	//T=read();
	while(T--)solve();
	return 0;
}



B 并查集+离散化
#include <bits/stdc++.h>
using namespace std;
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);
#define pb push_back
#define range(a) a.begin(),a.end()
typedef long long ll;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const double eps=1e-6;
const double PI=acos(-1.0);
inline ll read(){char ch;ll x=0;bool f=true;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f^=f;for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;return f?x:-x;}
const int N=5e5+7;
int s[N];
vector<int> son[N],ans[N],mp;
void add(int a,int b){son[a].pb(b),son[b].pb(a);}
int fin(int x){return lower_bound(range(mp),x)-mp.begin();}
int f[N];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void solve(){
    ll n=read(),m=read(),res=0,cnt=0;mp.resize(n+1,0);
    for(int i=1;i<=n;i++)mp[i]=s[i]=read(),f[i]=i;
    sort(range(mp)),mp.erase(unique(range(mp)),mp.end());
    for(int i=1;i<=n;i++)ans[fin(s[i])].pb(i);
    for(int i=1;i<=m;i++)add(read(),read());
    for(int i=mp.size()-1;i;i--){
        for(int x:ans[i]){
            cnt++;
            for(int j:son[x]){
                if(s[j]<s[x])continue;
                int fa=find(x),fb=find(j);
                if(fa!=fb)cnt--,f[fa]=fb;
            }
        }
        res+=(mp[i]-mp[i-1])*cnt;
    }
    //assert(cnt<=1);
    cout<<res;
}
int main(){
	int T=1;
	//T=read();
	//fre("1");
	while(T--)solve();
	return 0;
}



G LCA+前缀和
#include <bits/stdc++.h>
using namespace std;
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);
#define pb push_back
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const double eps=1e-6;
const double PI=acos(-1.0);
inline ll read(){char ch;ll x=0;bool f=true;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f^=f;for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;return f?x:-x;}
const int N=1e6+7;
ll s[N],fac[N],ifac[N];
int f[20][N],h[N];
vector<int> son[N];
void add(int a,int b){son[a].pb(b),son[b].pb(a);}
void dfs(int u,int v,int hh){f[0][u]=v;h[u]=hh;for(int x:son[u])if(x!=v)dfs(x,u,hh+1);}
void cdfs(int u,int v){fac[u]=fac[v];if(s[u]>s[v])fac[u]+=s[u]-s[v];for(int x:son[u])if(x!=v)cdfs(x,u);}
void icdfs(int u,int v){ifac[u]=ifac[v];if(s[u]<s[v])ifac[u]+=s[v]-s[u];for(int x:son[u])if(x!=v)icdfs(x,u);}
int next(int u,int x){for(int i=19;~i;i--)if((1<<i)&x)u=f[i][u];return u;}
int finlca(int u,int v){for(int i=19;~i;i--)if(f[i][u]!=f[i][v])u=f[i][u],v=f[i][v];return f[0][u];}
int lca(int u,int v){if(h[u]<h[v])swap(u,v);u=next(u,h[u]-h[v]);return u==v?v:finlca(u,v);}
void solve(){
    int n=read(),q=read();
    for(int i=1;i<=n;i++)s[i]=read();
    for(int i=1;i<n;i++)add(read(),read());
    dfs(1,0,1);
    for(int i=1;i<20;i++) for(int j=1;j<=n;j++) f[i][j]=f[i-1][f[i-1][j]];
    cdfs(1,0),icdfs(1,0);
    while(q--){
        int u=read(),v=read(),fa=lca(u,v);
        cout<<s[u]+ifac[u]-ifac[fa]+fac[v]-fac[fa]<<"\n";
    }
}
int main(){
	int T=1;
	//fre("10");
	while(T--)solve();
	return 0;
}


D 数组填数 大模拟
#include <bits/stdc++.h>
using namespace std;
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);
typedef long long ll;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
const double eps=1e-6;
const double PI=acos(-1.0);
inline ll read()
{
	char ch;ll x=0;bool f=true;
	for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f^=f;
	for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
	return f?x:-x;
}
const int N=1e3+7;
int s[N][N];
int t[10][10][10];
void dfs(int l,int r,int idx){
    int x=r-l+1;
    if(x<5){
        for(int i=0;i<x;i++)for(int j=0;j<x;j++)
            s[l+i][l+j]=t[x][i+1][j+1]+(t[x][i+1][j+1]?idx:0);
        return ;
    }
    else if(x%3==1){
        for(int k=0;k<=2;k+=2){
            for(int i=l;i<=r-4;i+=3){
                s[l+k][i]=s[l+1+k][i]=s[l+k][i+1]=idx++;
                s[l+1+k][i+1]=s[l+k][i+2]=s[l+1+k][i+2]=idx++;
                s[r-1-k][i+4]=s[r-k][i+4]=s[r-1-k][i+5]=idx++;
                s[r-k][i+5]=s[r-1-k][i+6]=s[r-k][i+6]=idx++;
                s[i+4][l+k]=s[i+4][l+1+k]=s[i+5][l+k]=idx++;
                s[i+5][l+1+k]=s[i+6][l+k]=s[i+6][l+1+k]=idx++;
                s[i][r-k]=s[i][r-1-k]=s[i+1][r-k]=idx++;
                s[i+1][r-1-k]=s[i+2][r-k]=s[i+2][r-1-k]=idx++;
            }
        }
        dfs(l+4,r-4,idx);
    }
    else {
        for(int i=l;i<=r-3;i+=3){
            s[l][i]=s[l+1][i]=s[l][i+1]=idx++;
            s[l+1][i+1]=s[l][i+2]=s[l+1][i+2]=idx++;
            s[r-1][i+2]=s[r][i+2]=s[r-1][i+3]=idx++;
            s[r][i+3]=s[r-1][i+4]=s[r][i+4]=idx++;
            s[i+2][l]=s[i+2][l+1]=s[i+3][l]=idx++;
            s[i+3][l+1]=s[i+4][l]=s[i+4][l+1]=idx++;
            s[i][r]=s[i][r-1]=s[i+1][r]=idx++;
            s[i+1][r-1]=s[i+2][r]=s[i+2][r-1]=idx++;
        }
        dfs(l+2,r-2,idx);
    }
}
void solve(){
    int n=read();
    if(n%3==0)return printf("NO"),void(0);
    cout<<"YES"<<"\n";

    t[2][1][1]=t[2][1][2]=t[2][2][1]=1;
    t[4][1][1]=t[4][1][2]=t[4][2][1]=1;
    t[4][4][4]=t[4][3][4]=t[4][4][3]=2;
    t[4][1][4]=t[4][1][3]=t[4][2][4]=3;
    t[4][4][1]=t[4][4][2]=t[4][3][1]=4;
    t[4][2][2]=t[4][2][3]=t[4][3][2]=5;

    dfs(1,n,1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            cout<<s[i][j]<<" ";
        cout<<"\n";
    }
}
int main()
{
	int T=1;
	//T=read();
	while(T--)solve();
	return 0;
}


M 树状数组DP
#include<bits/stdc++.h>
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define lowit(x) (x&-x)

#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back


#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);


using namespace std;

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll,ll> PII;
typedef pair<double,int> PDL;

const int INF=0x3f3f3f3f;
const int base = 131;
const double eps = 1e-6;
const double PI = acos(-1);

#define space putchar(' '),void(0)
#define enter putchar('\n'),void(0)
// <------------------------------->
namespace GenHelper
{
    int z1,z2,z3,z4,z5,u,res;
    int get()
    {
        z5=((z1<<6)^z1)>>13;
        z1=((int)(z1&4294967)<<18)^z5;
        z5=((z2<<2)^z2)>>27;
        z2=((z2&4294968)<<2)^z5;
        z5=((z3<<13)^z3)>>21;
        z3=((z3&4294967)<<7)^z5;
        z5=((z4<<3)^z4)>>12;
        z4=((z4&4294967)<<13)^z5;
        return (z1^z2^z3^z4);
    }
    int read(int m) {
        u=get();
        u>>=1;
        if(m==0)res=u;
        else res=(u/2345+1000054321)%m;
        return res;
    }
     void srand(int x)
    {
        z1=x;
        z2=(~x)^(0x23333333);
        z3=x^(0x12345798);
        z4=(~x)+51;
      	u = 0;
    }
}
using namespace GenHelper;
const int N=2e6+7,mod=1e9+7;
ll a[N],b[N];
int tr[N],id[N];
void add(int x,ll c){
    for(;x<N;x+=lowit(x)){
        tr[x]+=c;
        if(tr[x]>=mod)tr[x]-=mod;
    }
}
ll ask(ll x){
    ll res=0;
    for(;x;x-=lowit(x))res+=tr[x];
    return res-res/mod*mod;
}
void sortID(int n)
{
    static const int C = 16, D = 1 << C, mask = D - 1;
    static int cnt[D], tmp[N];{
        memset(cnt, 0, sizeof(cnt));
        for (int i = 1; i <= n; i++)
            ++cnt[a[i] & mask];
        for (int i = 1; i < D; i++)
            cnt[i] += cnt[i - 1];
        for (int i = n; i >= 1; i--)
            tmp[cnt[a[i] & mask]--] = i;
    }
    {
        memset(cnt, 0, sizeof(cnt));
        for (int i = 1; i <= n; i++)
            ++cnt[a[i] >> C];
        for (int i = 1; i < D; i++)
            cnt[i] += cnt[i - 1];
        for (int i = n; i >= 1; i--)
            id[cnt[a[tmp[i]] >> C]--] = tmp[i];
    }
}
int main(){
	int n,seed;scanf("%d %d",&n,&seed);
	srand(seed);
	for(int i=1;i<=n;i++)a[i]=read(0)+2147483648ull,b[i]=read(i),id[i]=i;
    sortID(n);
    for(int i=1;i<=n;i++){
		int c=id[i];
		ll x=(ask(c)-ask(c-b[c]-1)+1+mod)%mod;
		add(c,x);
	}
	printf("%lld",ask(n));
	return 0;
}


J 线段树维护DDP方程~
#include<bits/stdc++.h>
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
#define lowit(x) (x&-x)

#define range(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define pb push_back


#define sto                             \
    std::ios::sync_with_stdio(false);   \
    std::cin.tie(nullptr);              \
    std::cout.tie(nullptr);


using namespace std;

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll,ll> PII;
typedef pair<double,int> PDL;

const int INF=0x3f3f3f3f;
const int base = 131;
const double eps = 1e-6;
const double PI = acos(-1);

inline ll read(){
	ll x=0;char ch;bool f=true;
	for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f^=f;
	for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return f?x:-x;
}

#define space putchar(' '),void(0)
#define enter putchar('\n'),void(0)

void wr(ll x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10+48);
}
void wr(char *s){
	printf("%s",s);
}
// <------------------------------->
const int N=1e5+7;
char ch[11][4]={"","aaa","aac","aab","bbb","bba","bbc","ccc","cca","ccb","abc"};
int w[30][30];
int s[N];
vector<int> node[11];
bool p(int i,const char *s){
    int cnt[3]={0};
    for(int x=0;x<3;x++,i/=3)cnt[i%3]++,cnt[s[x]-'a']--;
    for(int x=0;x<3;x++)if(cnt[x])return false;
    return true;
}
void init(){
    for(int i=0;i<27;i++)for(int t=1;t<=10;t++)if(p(i,ch[t]))node[t].pb(i);
    for(int i=0;i<27;i++)for(int j=0;j<27;j++){
        w[i][j]=3;
        for(int k=0,c=27;k<3;k++,c/=3)
            if(i%c==j*c/27){
                w[i][j]=k;
                break;
            }
    }
}
struct T{
    int w[6][6];
    int ls,rs;
    void init(int c){
        memset(w,INF,sizeof w);
    	ls=rs=c;
        for(int i=0;i<node[c].size();i++)w[i][i]=0;
    }
    int money(){
        int ans=INF;
        for(int i=0;i<node[ls].size();i++)for(int j=0;j<node[rs].size();j++)
            ans=min(ans,w[i][j]);
        return ans+3;
    }
}tr[N<<2];
int a[6][6];
void up(T &v,const T &l,const T &r){
    memset(a,INF,sizeof a);
    memset(v.w,INF,sizeof v.w);
    for(int i=0;i<node[l.ls].size();i++)for(int j=0;j<node[l.rs].size();j++)for(int k=0;k<node[r.ls].size();k++)
        a[i][k]=min(a[i][k],l.w[i][j]+w[node[l.rs][j]][node[r.ls][k]]);
    for(int i=0;i<node[l.ls].size();i++)for(int j=0;j<node[r.ls].size();j++)for(int k=0;k<node[r.rs].size();k++)
        v.w[i][k]=min(v.w[i][k],a[i][j]+r.w[j][k]);
    v.ls=l.ls,v.rs=r.rs;
}
#define lson (o<<1)
#define rson (o<<1|1)
#define mid (l+r>>1)
void build(int o,int l,int r){
    if(l==r)return tr[o].init(s[l]);
    build(lson,l,mid),build(rson,mid+1,r);
    up(tr[o],tr[lson],tr[rson]);
}
void add(int o,int l,int r,int X,int c){
    if(l==r)return tr[o].init(c);
    if(X<=mid)add(lson,l,mid,X,c);
    else add(rson,mid+1,r,X,c);
    up(tr[o],tr[lson],tr[rson]);
}
T ask(int o,int l,int r,int L,int R){
    if(l==L&&R==r)return tr[o];
    if(R<=mid)return ask(lson,l,mid,L,R);
    else if(L>mid)return ask(rson,mid+1,r,L,R);
    T now;
    up(now,ask(lson,l,mid,L,mid),ask(rson,mid+1,r,mid+1,R));
    return now;
}
void solve(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++)s[i]=read();
    init();
    build(1,1,n);
    while(m--){
        int op=read(),l=read(),r=read();
        if(op==1)wr(ask(1,1,n,l,r).money()),enter;
        else add(1,1,n,l,r);
    }
}

int main(){
	#ifdef ONLINE_JUDGE
	#else
		//fre("1");
	#endif
	ll T=1;
	//T=read();
	for(int i=1;i<=T;i++)solve();
}


全部评论

(2) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐