AtCoder Beginner Contest 378

A - Pairing

思路

根据题意分类模拟判断即可

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int e;
    map<int,int> mp;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        for(int i=1;i<=4;i++)
        {
            cin>>e;
            mp[e]++;
        }
        for(auto i:mp){
            if(i.second==4){
                cout<<2<<endl;
                return 0;
            }
            if(i.second==3){
                cout<<1<<endl;
                return 0;
            }
            if(i.second==2&&mp.size()==2){
                cout<<2<<endl;
                return 0;
            }
            if(i.second==2&&mp.size()==3){
                cout<<1<<endl;
                return 0;
            }
            if(mp.size()==4){
                cout<<0<<endl;
                return 0;
            }
        }

        


        return 0;
    }

B - Garbage Collection

思路

对于每一个查询,找到第一个大于等于目标天数的值,暴力找会TLE,二分即可;

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 105, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int d[N];
    int q;
    int t,s;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            cin>>d[i];
        }
        cin>>q;
        while(q--)
        {
            cin>>t>>s;
            int l=0;int r=MAX;
            while(l<r)
            {
                int mid=(l+r)>>1;
                if(mid*a[t]+d[t]>=s)r=mid;
                else l=mid+1;
            }
            cout<<l*a[t]+d[t]<<endl;
        }


        return 0;
    }

C - Repeating

思路

对于每个字符,建立索引数组,对于每次构造,二分查找目标,时间复杂度\(O(nlogn)\);

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int n;
    int a[N];
    int b[N];
    map<int,vector<int>> mp;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            mp[a[i]].pb(i);
        }
        for(int i=1;i<=n;i++){
            int l=0;int r=mp[a[i]].size()-1;
            while(l<r)
            {
                int mid=(l+r+1)>>1;
                if(mp[a[i]][mid]<i)l=mid;
                else r=mid-1;
            }
            if(mp[a[i]][l]!=i)cout<<mp[a[i]][l]<<" ";
            else cout<<"-1"<<" ";
        }


        return 0;
    }

D - Count Simple Paths

思路

第一次看错了,以为是大于 \(K\) 的路径都要,结果只是找等于的,数据非常小,直接DFS;

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 12, MAX = 1e9, INF = -1e9;

    int h,w,k;
    char g[N][N];
    bool st[N][N];
    int ans=0;
    int dx[5]={0,1,-1,0,0};
    int dy[5]={0,0,0,1,-1};

    void dfs(int x,int y,int l)
    {
        if(l>=k+1){
            ans++;
            return ;
        }
        
        st[x][y]=true;
        for(int i=1;i<=4;i++)
        {
            int a=x+dx[i];
            int b=y+dy[i];
            if(a>=1&&a<=h&&b>=1&&b<=w&&g[a][b]!='#'&&!st[a][b]){
                st[a][b]=true;
                dfs(a,b,l+1);
                st[a][b]=false;
            }
        }
    }

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>h>>w>>k;
        for(int i=1;i<=h;i++)
        {
            for(int j=1;j<=w;j++)
            {
                cin>>g[i][j];
            }
        }
        for(int i=1;i<=h;i++)
        {
            for(int j=1;j<=w;j++)
            {
                if(g[i][j]!='#'){
                    memset(st,false,sizeof st);
                    dfs(i,j,1);
                }
            }
        }
        cout<<ans<<endl;

        return 0;
    }

E - Mod Sigma Problem

思路

所求式子中需要求和,想到前缀和预处理,但是无法处理 \(mod\) 运算,不妨将前缀和直接定义为模运算之后的和,即 \(S [i]=(A [1]+A [2]+\dots+A [i]) \mathbin{\mathrm{mod}} M\), 这样定义后,原式将会退化:

\[\sum_{1\leq l\leq r\leq N}\left(\left(\sum_{l\leq i\leq r} A_i\right)\mathbin{\mathbin{mod}}M \right)= \sum_{1\leq l\leq r\leq N}(S_r-S_{l-1})\mathbin{\mathbin{mod}}M \]

此时由于 \(S_i<M\),

\[(S_r-S_{l-1})\mathbin{\mathrm{mod}} M=S_r-S_{1-1}+ \begin{cases}0 & (S_{l-1} \leq S_r) \\M & (S_{l-1}>S_r),\end{cases} \]

\(X_r\)为小于时的数量,则:

\[\sum_{r=1}^N \sum_{l=1}^r(S_r-S_{l-1}) \mathbin{\mathrm{mod}} M= \sum_{r=1}^N \left(S_r\times r- \sum_{l=1}^rS_{l-1}+ M \times X_r\right). \]

最后用树状数组维护 \(X_r\) ,时间复杂度为\(O(nlogm)\);

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int n,m,a[N],s[N],g[N],ans,tr[N];

    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x)
    {
        if(x==0)
        {
            return;
        }
        while(x<=m)
        {
            tr[x]++;
            x+=lowbit(x);
        }
    }
    int sum(int x)
    {
        int sum=0;
        while(x>0)
        {
            sum+=tr[x];
            x-=lowbit(x);
        }
        return sum;
    }
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            a[i]%=m;
            s[i]=(s[i-1]+a[i])%m;
            g[i]=g[i-1]+s[i];
        }
        for(int i=1;i<=n;i++)
        {
            ans=ans+i*s[i]-g[i-1]+m*(sum(m)-sum(s[i]));
            add(s[i]);
        }
        cout<<ans<<endl;
        return 0;
    }

t.b.c.

posted @ 2024-11-05 11:27  Oaths  阅读(61)  评论(0)    收藏  举报