《武汉大学2020年新生程序设计竞赛》

A:签到。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<string,string> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

int w[105];
int main()
{
    int ca;ca = read();
    while(ca--)
    {
        int n,m;n = read(),m = read();
        for(int i = 1;i <= n;++i) w[i] = read();
        sort(w + 1,w + n + 1);
        double ma = m;
        int f = 0;
        for(int i = 1;i <= n;++i)
        {
            if(ma >= w[i])
            {
                ma -= w[i] * 0.7;
            }
            else f = 1;
        }
        printf("%s\n",f ? "no" : "yes");
    }
    return 0;
}
View Code

C:签到

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<string,string> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

int main()
{
    int n;n = read();
    while(n--)
    {
        string s;cin >> s;
        int len = 0,ans = 0;
        for(auto v : s)
        {
            if(v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u') len++;
            else len = 0;
            ans = max(ans,len);
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

J:记录一下头两个刚好卡住爆杀的位置,然后讨论下即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<string,string> pii;
const int N = 1e3+5;
const int M = 1e6+5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

int h[N];
int main()
{
    int n,a,k;n = read(),a = read(),k = read();
    for(int i = 1;i <= n;++i) h[i] = read();
    int ans = 0,tag = 0,pre = 0,f = 0;
    for(int i = 1;i <= n;++i)
    {
        if(h[i] == k)
        {
            if(tag == 1){ans = i;break;}
            else if(tag == 0)
            {
                if(i == n){ans = i;break;}
                pre = i;
            }
            tag++;
        }
        else if(h[i] > k)
        {
            if(tag == 0)
            {
                int j = i + 1;
                while(j <= n && h[j] < k) j++;
                if(j > n) ans = n;
                else if(h[j] == k) ans = j;
                else ans = j - 1;
            }
            else if(tag == 1) ans = pre + 1;
            break;
        }
        else f++;
    }
    if(f == n) ans = n;
    printf("%d\n",ans);
    return 0;
}
View Code

D:记录0的位置,然后枚举开始二分找答案即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<string,string> pii;
const int N = 1e6+5;
const int M = 1e6+5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

int a[N],b[N];
int main()
{
    int n;n = read();
    while(n--)
    {
        string s;cin >> s;
        int k;k = read();
        if(k == 0)
        {
            int len = 0,ans = 0;
            for(auto v : s)
            {
                if(v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u') len++;
                else len = 0;
                ans = max(ans,len);
            }
            printf("%d\n",ans);
        }
        else
        {
            int cnt = 0;
            for(int i = 0;i < s.size();++i)
            {
                if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') a[i + 1] = 1;
                else a[i + 1] = 0,b[++cnt] = i + 1;
            }
            int ans = 0;
            for(int i = 1;i <= s.size();++i)
            {
                int tmp;
                if(a[i] == 1)
                {
                    int pos = upper_bound(b + 1,b + cnt + 1,i) - b;
                    if(pos > cnt) tmp = s.size() - i + 1;
                    else
                    {
                        int ma = b[pos + k];
                        if(pos + k > cnt) tmp = s.size() - i + 1;
                        else tmp = ma - i;
                    }
                }
                else
                {
                    int pos = lower_bound(b + 1,b + cnt + 1,i) - b,ma;
                    if(pos + k > cnt) ma = s.size();
                    else ma = max(b[pos + k - 1],b[pos + k] - 1);
                    tmp = ma - i + 1;
                }
               // printf("i is %d tmp is %d\n",i,tmp);
                ans = max(ans,tmp);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
View Code

E:非常好的一道题。第一眼觉得是主席树,但是没想出来。

赛后看了大佬们的思路,居然是分块(妙啊

思路:考虑到分块后复杂度为 330 * 1e5,那么复杂度还是够得 。

首先,我们考虑一下询问,因为每个块最多只有330多。

那么当两个询问是相邻块或者在同一个块中时,直接暴力去统计即可。

当不是的时候,我们可以预处理出中间所有完整的块里的最值。

那么,如果中间的块价值要加上首尾两个不完整的块的话。

那个最大值只可能是在首尾的两个块中,所以我们再去看看首尾块中的值是否会比中间的最大值大。

那么,显然首尾块中的个数,要加上中间的个数,所以这里记录一个前缀和即可O(1)求出。

注意每次统计完次数后,都需要减去。

中间的最值统计写错,调了很久,最后造了下数据才测出来。

一开始是这样求的块之间最值:

for(int i = 1;i <= bel[n];++i)
    {
        for(int j = L[i];j <= n;++j)
        {
            cnt[a[j]]++;
            mx[i][bel[j]] = max(mx[i][bel[j]],b[a[j]] * cnt[a[j]]);
        }
        for(int j = L[i];j <= n;++j) cnt[a[j]]--;
    }

但是后面发现,这样只有在遇到最值的时候才会更新到最值,如果那个块里没有那个最值,那么就更新不到了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 998244353;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

LL a[N],b[N],mx[405][405],cnt[N],sum[405][N];
int L[405],r[405],bel[N];
int main()
{
    int n,m;n = read(),m = read();
    int tot = 0;
    for(int i = 1;i <= n;++i) a[i] = read(),b[++tot] = a[i];
    sort(b + 1,b + tot + 1);
    int len = unique(b + 1,b + tot + 1) - b - 1;
    int blsize = sqrt(n);
    for(int i = 1;i <= n;++i) bel[i] = (i - 1) / blsize + 1;
    for(int i = 1;i <= n;++i) a[i] = lower_bound(b + 1,b + len + 1,a[i]) - b;
    for(int i = 1;i <= bel[n];++i) 
    {
        L[i] = blsize * (i - 1) + 1;
        r[i] = min(blsize * i,n);
    }
    for(int i = 1;i <= n;++i) sum[bel[i]][a[i]]++;
    for(int i = 1;i <= bel[n];++i)
        for(int j = 1;j <= len;++j) sum[i][j] += sum[i - 1][j];
    for(int i = 1;i <= bel[n];++i)
    {
        LL tmp = 0;
        for(int j = L[i];j <= n;++j)
        {
            cnt[a[j]]++;
            tmp = max(tmp,b[a[j]] * cnt[a[j]]);
            if(j == r[bel[j]]) mx[i][bel[j]] = tmp;
        }
        for(int j = L[i];j <= n;++j) cnt[a[j]]--;
    }
    LL ans = 0;
    while(m--)
    {
        LL ll,rr;ll = read(),rr = read();
        ll = (ll ^ ans) % n + 1;
        rr = (rr ^ ans) % n + 1;
        if(ll > rr) swap(ll,rr);
      //  printf("L is %d r is %d\n",ll,rr);
        if(bel[ll] == bel[rr]) 
        {
            LL ma = -1;
            for(int j = ll;j <= rr;++j)
            {
                cnt[a[j]]++;
                ma = max(ma,b[a[j]] * cnt[a[j]]);
            }
            for(int j = ll;j <= rr;++j) cnt[a[j]]--;
            ans = ma;
        }
        else
        {
            LL ma = -1;
            for(int j = ll;j <= r[bel[ll]];++j) 
            {
                cnt[a[j]]++;
                LL tmp = 0;
                if(bel[ll] + 1 <= bel[rr] - 1) tmp = sum[bel[rr] - 1][a[j]] - sum[bel[ll]][a[j]];
                ma = max(ma,b[a[j]] * (tmp + cnt[a[j]]));
            } 
            for(int j = L[bel[rr]];j <= rr;++j) 
            {
                cnt[a[j]]++;
                LL tmp = 0;
                if(bel[ll] + 1 <= bel[rr] - 1) tmp = sum[bel[rr] - 1][a[j]] - sum[bel[ll]][a[j]];
                ma = max(ma,b[a[j]] * (tmp + cnt[a[j]]));
            }
            for(int j = ll;j <= r[bel[ll]];++j) cnt[a[j]]--;
            for(int j = L[bel[rr]];j <= rr;++j) cnt[a[j]]--;
            
            if(bel[ll] + 1 <= bel[rr] - 1) ma = max(ma,mx[bel[ll] + 1][bel[rr] - 1]);
            ans = ma;
        }
        printf("%lld\n",ans);
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2020-11-23 10:58  levill  阅读(171)  评论(0编辑  收藏  举报