acm周赛1

C
题意:求A*B+C=N
A,B,C种类个数

#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
void solve()
{
    int sum=0;
    int N;
    cin>>N;
    for(int i=1;i<N;i++)
    {
        sum+=(N-1)/i;
    }
    cout<<sum;
}

signed main() {
    int _=1;
    while(_--) {
        solve();
    }
    return 0;
}
#include <bits/stdc++.h>
//#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long  ll;
const int maxn=1e6+5;
int dp[maxn];
void init()
{
    dp[1]=1;
    dp[2]=2;
    dp[3]=2;
    for(int i=4;i<maxn;i++){
        int xx=i;
        int sum=1;
        for(int j=2;j*j<=xx;j++)
        {
            int ans=1;
            while(xx%j==0)
            {
                ans++;
                xx/=j;
            }
            sum*=ans;
        }
        if(xx!=1)
            sum*=2;
        dp[i]=sum;
    }
}
void solve()
{
    int sum=0;
    int n;
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int xx=n-i;
        sum+=dp[xx];
    }
    cout<<sum;
}

int main() {
    int _=1;
    while(_--) {
        init();
        solve();
    }
    return 0;
}

D
题意:
1-n
可以走k个不相交的区间,问到n的路径有几种情况。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+5;
const int mod=998244353;
vector<pair<int,int> >vv;
int dp[maxn]={0};
int sum[maxn]={0};
void solve()
{
    vv.clear();
   int n,k;
   cin>>n>>k;
   for(int i=1;i<=k;i++)
   {
       int l,r;
       cin>>l>>r;
       vv.push_back({l,r});
   }
   dp[1]=1;
   sum[1]=1;
   for(int i=2;i<=n;i++)
   {
       for(int j=0;j<vv.size();j++)
       {
           int l=i-vv[j].second,r=i-vv[j].first;
           l=max(l,0ll);
           r=max(r,0ll);
           dp[i]=(dp[i]+(sum[r]-sum[l]+dp[l])%mod)%mod;
       }
       sum[i]=(sum[i-1]+dp[i])%mod;
   }
   cout<<dp[n];
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _=1;
    //cin>>_;
    while(_--)
        solve();
}
#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long  ll;
const int maxn=2e5+5;
const int mod=998244353;
vector<pair<int,int> >vv;
int dp[maxn];
int tree[maxn*4];
int lazy[maxn*4];
void init()
{
    vv.clear();
}
void  build(int l,int r,int t) {
    lazy[t] = 0;
    tree[t]=0;
    if (l == r)tree[t] = dp[l];
    else{
        int mid=(l+r)>>1;
        build(l,mid,t<<1);
        build(mid+1,r,t<<1|1);
    }
}
void pushdown(int t)
{
    if(lazy[t]==0)return ;
    lazy[t<<1]+=lazy[t];
    lazy[t<<1]%=mod;
    lazy[t<<1|1]+=lazy[t];
    lazy[t<<1|1]%=mod;
    tree[t<<1]+=lazy[t];
    tree[t<<1]%=mod;
    tree[t<<1|1]+=lazy[t];
    tree[t<<1|1]%=mod;
    lazy[t]=0;
}
void update(int l,int r,int t,int L,int R,int d)
{
    if(L>r||R<l)
        return ;
    if(l>=L&&r<=R)
    {
        tree[t]+=d;
        tree[t]%=mod;
        lazy[t]+=d;
        lazy[t]%=mod;
    }
    else
    {
        pushdown(t);
        int mid=(l+r)>>1;
        if(mid>=L)
            update(l,mid,t<<1,L,R,d);
        if(mid<R)
            update(mid+1,r,t<<1|1,L,R,d);
    }
}
int query(int l,int r,int t,int L,int R)
{
    if(l>=L&&r<=R)return tree[t];
    if(l>R||r<L)return 0;
    int mid=(l+r)>>1;
    pushdown(t);
    if(mid>=L)
        return query(l,mid,t<<1,L,R);
    if(mid<R)
        return query(mid+1,r,t<<1|1,L,R);
}
void solve()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=k;i++)
    {
        int l,r;
        cin>>l>>r;
        vv.push_back({l,r});
    }
    dp[1]=1;
    update(1,n,1,1,1,1);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<vv.size();j++)
        {
            pair<int,int> xx=vv[j];
            if(i!=1)
                dp[i]=query(1,n,1,i,i)%mod;
            if(dp[i]!=0)
                update(1,n,1,i+xx.first,i+xx.second,dp[i]);
        }
    }
    cout<<dp[n];
}

signed main() {
    int _=1;
    while(_--) {
        init();
        solve();
    }
    return 0;
}

E
题意
ai+1=ai*ai%m
给你一个初始值是x ,然后余数是m的值,然后让你求前N项的和

#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
map<int,int>mm;
const int maxn=1e5+5;
int dp[maxn]={0};
void solve()
{
    mm.clear();
    int N,x,m;
    cin>>N>>x>>m;
    int cnt=x;
    mm[cnt]=1;
    dp[1]=cnt;
    int i=2;
    int l,r;
    while(1)
    {
        cnt=(cnt*cnt)%m;
        if(cnt==0)
        {
            cout<<dp[i-1];
            return;
        }
        if(cnt==1)
        {
            cout<<dp[i-1]+N-(i-1);
            return ;
        }
        if(mm[cnt]==0)
        {
            dp[i]=dp[i-1]+cnt;
            mm[cnt]=i;
            i++;
        }
        else
        {
            l=mm[cnt];
            r=i;
            break;
        }
    }
    int res=dp[l-1];
    int yy=dp[r-1]-dp[l-1];
    int xx=r-l;
    N-=l-1;
    int shang=N/xx;
    res+=shang*yy;
    int yv=N%xx;
    res+=dp[l-1+yv]-dp[l-1];
    cout<<res;
}

signed main() {
    int _=1;
    while(_--) {
        solve();
    }
    return 0;
}

F
思路其实很简单,但是碰到区间更新会T
很显然用线段树更新

#include <bits/stdc++.h>
#define int long long
//#pragma GCC optimize(2)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int inf=1e9+5;
const int maxn=2e5+5;
int n,q;
int di[maxn*4],ri[maxn*4],lazydi[maxn*4],lazyri[maxn*4];
void build(int xx)
{
    for(int i=1;i<maxn*4;i++)
    {
        di[i]=xx;
        ri[i]=xx;
        lazydi[i]=xx;
        lazyri[i]=xx;
    }
}
void pushdowndi(int t)
{
    lazydi[t<<1]=min(lazydi[t<<1],lazydi[t]);
    lazydi[t<<1|1]=min(lazydi[t<<1|1],lazydi[t]);
    di[t<<1]=min(di[t<<1],lazydi[t<<1]);
    di[t<<1|1]=min(di[t<<1|1],lazydi[t<<1|1]);
}
void updatedi(int l,int r,int t,int L,int R,int d)
{
    if(l>R||r<L)
        return;
    if(l>=L&&r<=R)
    {
        lazydi[t]=min(lazydi[t],d);
        di[t]=min(lazydi[t],di[t]);
    }
    else
    {
        pushdowndi(t);
        int mid=(l+r)>>1;
        if(mid>=L)
            updatedi(l,mid,t<<1,L,R,d);
        if(mid<R)
            updatedi(mid+1,r,t<<1|1,L,R,d);
    }
}
int querydi(int l,int r,int t,int L,int R)
{
    if(l>=L&&r<=R)
        return di[t];
    if(l>R||r<L)
        return inf;
    int mid=(l+r)>>1;
    pushdowndi(t);
    if(mid>=L)
        return querydi(l,mid,t<<1,L,R);
    if(mid<R)
        return querydi(mid+1,r,t<<1|1,L,R);
}
void pushdownri(int t)
{
    lazyri[t<<1]=min(lazyri[t<<1],lazyri[t]);
    lazyri[t<<1|1]=min(lazyri[t<<1|1],lazyri[t]);
    ri[t<<1]=min(ri[t<<1],lazyri[t<<1]);
    ri[t<<1|1]=min(ri[t<<1|1],lazyri[t<<1|1]);
}
void updateri(int l,int r,int t,int L,int R,int d)
{
    if(l>R||r<L)
        return;
    if(l>=L&&r<=R)
    {
        lazyri[t]=min(lazyri[t],d);
        ri[t]=min(lazyri[t],ri[t]);
    }
    else
    {
        pushdownri(t);
        int mid=(l+r)>>1;
        if(mid>=L)
            updateri(l,mid,t<<1,L,R,d);
        if(mid<R)
            updateri(mid+1,r,t<<1|1,L,R,d);
    }
}
int queryri(int l,int r,int t,int L,int R)
{
    if(l>=L&&r<=R)
        return ri[t];
    if(l>R||r<L)
        return inf;
    int mid=(l+r)>>1;
    pushdownri(t);
    if(mid>=L)
        return queryri(l,mid,t<<1,L,R);
    if(mid<R)
        return queryri(mid+1,r,t<<1|1,L,R);
}
void solve()
{
    cin>>n>>q;
    int sum=(n-2)*(n-2);
    build(n);
    for(int i=1;i<=q;i++)
    {
        int op,x;
        cin>>op>>x;
        if(op==1)
        {
            int d=querydi(1,n,1,x,x);
            sum-=(d-2);
            updateri(1,n,1,2,d-1,x);
        }
        else
        {
            int r=queryri(1,n,1,x,x);
            sum-=(r-2);
            updatedi(1,n,1,2,r-1,x);
        }
    }
    cout<<sum;
}
signed main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int _=1;
    while(_--) {
        solve();
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int n,x,y,q,op,k,r[N],c[N];
int main(){
    cin>>n>>q;
    x=y=n;
    ll ans=(n-2LL)*(n-2LL);
    while(q--){
        cin>>op>>k;
        if(op==1) {
            if (k < y) {
                ans -= x - 2;
                while (y > k) c[y--] = x - 2;
            } else ans -= c[k];
        }else{
            if (k < x) {
                ans -= y - 2;
                while (x > k) r[x--] = y - 2;
            } else ans -= r[k];
        }
    }
    cout<<ans;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值