牛客网暑期ACM多校训练营(第十场)

jls场
A
签到

#include <bits/stdc++.h>
using namespace std;

const long long mod=998244353;
int n,m,t,c,l,r;
long long a[100007],sum[100007];


long long cal(long long a, long long b){
    long long sum = 1;
    a = a % mod;
    while (b > 0) {
        if (b % 2 == 1)     //判断是否是奇数,是奇数的话将多出来的数事先乘如sum
            sum = (sum * a) % mod;
        b /= 2;
        a = (a * a) % mod;// 不断的两两合并再取模,减小a和b的规模
    }
    return sum;
}


int main(){
    long long x,y;
    cin>>t;
    while (t--){
        scanf ("%d%d",&n,&m);
        y=cal(2,1ll*n*m);
        sum[0]=0;
        for (int i=1;i<=n;i++){
            scanf ("%lld",&a[i]);
            sum[i]=(sum[i-1]+a[i])%mod;
        }
        for (int i=1;i<=m;i++){
            scanf ("%d%d%d",&c,&l,&r);
            if (c==2){
                x=(sum[r]-sum[l-1]+mod)%mod;
                x=(x*y+mod)%mod;
                printf("%lld\n",x);
            }
        }
    }
    return 0;
}

D
差分,暴力

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll power(ll n,ll p){
    ll ans=1;
    ll base=n;
    while(p){
        if(p&1)ans=ans*base%mod;
        p>>=1;
        base=base*base%mod;
    }
    return ans;
}
ll fac[200007];
ll inv[200007];
inline ll C(ll x,ll y){
    if(x<0||y<0||x<y)return 0;
    ll ans=fac[x];
    ans=ans*inv[y]%mod;
    ans=ans*inv[x-y]%mod;
    return ans;
}
void debugC(){
    ll x,y;
    while(cin>>x>>y)cout<<C(x,y)<<endl;
}
struct node{
    ll typ,l,r,x;
}rec[100003];
ll tot;
ll T,n,q;
int main(){
    fac[0]=inv[0]=1;
    for(ll i=1;i<=200005;i++){
        fac[i]=fac[i-1]*i%mod;
        inv[i]=power(fac[i],mod-2);
    }
    //  debugC();
    scanf("%lld",&T);
    while(T--){
        tot=0;
        scanf("%lld%lld",&n,&q);
        ll typ,l,r,x;
        while(q--){
            scanf("%lld",&typ);
            if(typ==1){
                scanf("%lld%lld%lld",&l,&r,&x);
                rec[++tot]=(node){typ,l,r,x};
            }
            else if(typ==2){
                rec[++tot]=(node){typ,0,0,0};
            }
            else{
                scanf("%lld%lld",&l,&r);
                l--;
                ll flor=1;
                ll ans1=0,ans2=0;
                for(ll j=tot;j>=1;j--){
                    if(rec[j].typ==2)flor++;
                    else {
                        ans1=(ans1+C(r-rec[j].l+flor,flor)*rec[j].x)%mod;
                        ans1=(ans1-C(r-(rec[j].r+1)+flor,flor)*rec[j].x)%mod;
                        if(ans1<0)ans1+=mod;
                        ans2=(ans2+C(l-rec[j].l+flor,flor)*rec[j].x)%mod;
                        ans2=(ans2-C(l-(rec[j].r+1)+flor,flor)*rec[j].x)%mod;
                        if(ans2<0)ans2+=mod;
                    }
                }
                ans1=(ans1-ans2+mod)%mod;
                printf("%lld\n",ans1);
            }
        }
    }
}

E
数论,容斥,暴力卡常

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll power(ll n,ll p){
    ll ans=1;
    ll base=n;
    while(p){
        if(p&1){
            ans=ans*base%mod;
        }
        p>>=1;
        base=base*base%mod;
    }
    return ans;
}
ll T,n,M;
ll a[200003];
ll b[200003];
ll cnt[200003];
ll g[200003];
ll res[200003];
ll inv[200003];
ll tot;
int main(){
    for(ll i=1;i<=200000;i++){
        inv[i]=power(i,mod-2);
    }
    scanf("%lld",&T);
    while(T--){
        scanf("%lld%lld",&n,&M);
        memset(b,0,sizeof(b));
        memset(cnt,0,sizeof(cnt));
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            b[a[i]]++;
        }
        for(ll i=1;i<=100000;i++){
            for(ll j=1;j*i<=100000;j++){
                cnt[i]+=b[j*i];
            }
        }
        ll ans=0;
        for(ll m=1;m<=M;m++){
            ll tmp=0;
            tot=0;
            for(ll i=1;i*i<=m;i++){
                if(m%i==0){
                    g[++tot]=i;
                    if(i*i==m)break;
                    g[++tot]=m/i;
                }
            }
            sort(g+1,g+1+tot);
            for(ll i=tot;i>=1;i--){
                res[i]=power(m+1,cnt[g[i]])-1;
                for(ll j=i+1;j<=tot;j++){
                    if(g[j]%g[i]==0){
                        res[i]-=res[j];
                        if(res[i]<0)res[i]+=mod;
                    }
                }
                tmp=(tmp+res[i]*inv[m/g[i]])%mod;
            }
            ans^=tmp;
        }
        printf("%lld\n",ans);
    }
}

F
floyd一遍,枚举一条边归并d数组

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll power(ll n,ll p){
    ll ans=1;
    ll base=n;
    while(p){
        if(p&1)ans=ans*base%mod;
        p>>=1;
        base=base*base%mod;
    }
    return ans;
}
int T;
int n;
ll g[505][505];
struct node{
    int id;
    ll dis;
}rec[505][505];
bool vis[505];
bool cmp(node a,node b){
    return a.dis<b.dis;
}
bool check(int i,int u,int j,int v){
    if(u>n)return v;
    if(v>n)return u;
    return rec[i][u].dis<rec[j][v].dis;
}
int main(){
    scanf("%d",&T);
    while(T--){
        ll ans=0;
        ll sum=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%lld",&g[i][j]);
                sum+=g[i][j];
                sum%=mod;
            }
        }
        sum=sum*(n-2)%mod*(n+1)%mod;
        sum=sum*power(4,mod-2)%mod;
        ans=sum;
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                rec[i][j]=(node){j,g[i][j]};
            }
            sort(rec[i]+1,rec[i]+1+n,cmp);
        }
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                memset(vis,false,sizeof(vis));
                int res=n-2;
                int u=0,v=0;
                while(res){
                    if(check(i,u+1,j,v+1)){
                        u++;
                        int id=rec[i][u].id;
                        ll dis=rec[i][u].dis;
                        if(id==i||id==j||vis[id])continue;
                        vis[id]=true;
                        res--;
                        ans=(ans+res*dis)%mod;
                    }
                    else {
                        v++;
                        int id=rec[j][v].id;
                        ll dis=rec[j][v].dis;
                        if(id==i||id==j||vis[id])continue;
                        vis[id]=true;
                        res--;
                        ans=(ans+res*dis)%mod;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
}

H
类欧几里德

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t;
ll a,b,c,d,n;

__int128 f(__int128 a, __int128 b, __int128 c, __int128 n){
    if(a==0){
        return (n+1)*(b/c);
    }
    else if(a>=c || b>=c){
        return f(a%c,b%c,c,n)+n*(n+1)/2*(a/c)+(n+1)*(b/c);
    }
    else{
        __int128 m=(a*n+b)/c;
        return n*m-f(c,c-b-1,a,m-1);
    }
}

void print(__int128 x){
    if(x<10) putchar('0'+x);
    else{
        print(x/10);
        putchar('0'+x%10);
    }
}

int main(){
    scanf("%d",&t);
    /*
    while(true){
        ll a,b,c,n;
        scanf("%lld%lld%lld%lld",&a,&b,&c,&n);
        cout<<(ll)f(a,b,c,n)<<endl;
    }
    */
    while(t--){
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        ll g=__gcd(a,b);
        a/=g;
        b/=g;
        g=__gcd(c,d);
        c/=g;
        d/=g;
        if(a==c && b==d){
            printf("-1\n");
            continue;
        }
        if(a*d<b*c){
            swap(a,c);
            swap(b,d);
        }
        n=d*(a+b)/(a*d-b*c);
        //cout<<(ll)f(c,d,d,c)<<" "<<(ll)f(a,0,b,n-1)<<endl;
        __int128 ans=f(c,d,d,n)-f(a,0,b,n-1);
        assert(ans>=2);
        print((ans-1)%998244353);
        putchar('\n');
    }
    return 0;
}

J
上香

#include <bits/stdc++.h>
using namespace std;
int T,n;
char s[1000003];
int len;
int nxt[1000003][26];
char t[1000003];
void insert(char c){
    s[++len]=c;
    for(int i=len-1;i>=0;i--){
        nxt[i][c-'a']=len;
        if(s[i]==c)break;
    }
}
int main(){
    scanf("%d",&T);
    while(T--){
        len=0;
        memset(nxt,-1,sizeof(nxt));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",t);
//          cout<<nxt[5]['i'-'a']<<endl;
            for(int j=0,k=nxt[0][t[0]-'a'];t[j];j++){
                if(k==-1){
                    insert(t[j]);
                    continue;
                }
                k=nxt[k][t[j+1]-'a'];
            }
        }
        for(int i=1;i<=len;i++)printf("%c",s[i]);
        printf("\n");
    }
}

托牛客睿智积分计算公式的福,竟然苟到了总排名第十。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值