ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

百度之星初赛第三场 2 4 6

2022-09-04 19:01:59  阅读:198  来源: 互联网

标签:tmp int pos 初赛 yy xx 之星 第三场 fo


感觉B和D都有问题,但是就按照正常思路写吧。。

B:如果是平方数,且该数的根是质数,就是YES,否则NO;

#define int ll
const int N= 1000010;
int n;
int primes[N], cnt;
bool st[N];

void get_primes(){
    for(int i=2;i<=N;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]<=N/i;j++){
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }
}

void solve()
{
//    cin>>n>>m;
    cin>>n;
    st[1] = 1;
    while(n -- ) {
        ll a;cin>>a;
        ll t = sqrt(a);
        if(t * t != a) {
            NO;
            continue;
        }
        if(!st[t]) {
            YES;
        } else {
            NO;
        }
    }
}

D:如果有空洞连续出现,就删掉。然后遍历所有联通块,看看这些联通块中有多少空洞

//#define int ll
const int N = 1010;
int n,m,ans1,ans2,ans3;

char mp[N][N]; 
bool vis[N][N];
bool del[N][N];

void bfs(int x,int y) {
    queue<pii> q;
    q.push({x,y});
    int ans = 0;
    while(q.size()) {
        auto tmp = q.front();q.pop();
        if(vis[tmp.x][tmp.y]) continue;
        vis[tmp.x][tmp.y] = 1;
        fo(i,0,3) {
            int xx = tmp.x + dx[i],yy = tmp.y + dy[i];
            if(xx <= 0 || yy <= 0 || xx > n || yy > m) continue;
            if(mp[xx][yy] == '.' && !del[xx][yy]) {
                ans ++ ;
                del[xx][yy] = 1;
            }
            if(vis[xx][yy] || mp[xx][yy] == '.' || del[xx][yy]) continue;
            mp[xx][yy] = '.';
            del[xx][yy] = 1;
            q.push({xx,yy});
        }
    }
    
    if(ans == 0) {
        ans1++;
    }
    else if(ans == 1) ans2 ++ ;
    else if(ans == 2) ans3 ++ ; 
}

void dell(int x,int y) {
    queue<pii>q;
    q.push({x,y});
    bool f = 0;
    fo(i,0,3) {
        auto tmp = q.front();
        int xx = tmp.x + dx[i],yy = tmp.y + dy[i];
        if(mp[xx][yy] == '.') f = 1;
    }
    if(!f) return;
    del[x][y] = 1;
    while(q.size()) {
        auto tmp = q.front();q.pop();
        if(vis[tmp.x][tmp.y]) continue;
        vis[tmp.x][tmp.y] = 1;
        fo(i,0,3) {
            int xx = tmp.x + dx[i],yy = tmp.y + dy[i];
            if(xx <= 0 || yy <= 0 || xx > n || yy > m) continue;
            if(vis[xx][yy] || mp[xx][yy] == '#') continue;
            del[xx][yy] = 1;
            q.push({xx,yy});
        }
    }
}

void solve()
{
    cin>>n>>m;
    fo(i,1,n) {
        fo(j,1,m) {
            cin>>mp[i][j];
        }
    }
    ms(vis,0);
    fo(i,1,n){
        fo(j,1,m) {
            if(mp[i][j] == '.') {
                dell(i,j);
            }
        }
    }
    
    
    ms(vis,0);
    fo(i,1,n) {
        fo(j,1,m) {
            if(mp[i][j] == '#') {
                bfs(i,j);
            }
        }
    }
    cout<<ans1<<' ' <<ans2<<' ' <<ans3<<endl;
}

6.区间最大值

先预处理数前缀和 sum[i] 

用单调栈,预处理出每个点后面离它最近的比它大的数的位置pos。

[ i , pos - 1 ] 之间的最大值就是 a[i] 。

倒序遍历结果 计算每个 [i, n] 之间的总结果 suf[i] = suf[pos]  + a[i] * (sum[pos - 1] - sum[i-1] )

将 l 和 r 离线下来在倒序遍历的时候记录答案就可以了,maxx 表示 l 到 r 的区间最大值,pos 表示 区间最大值的位置 ,las[pos] 表示比 pos 还要大的数的位置

ans = suf[l] - suf[las[pos]] + maxx * (sum[r] - sum[las[pos] - 1]);

//#define int ll
const int N = 5e5+10,M = 1e6+10,inf = 1e6;
int n,q,a[N],top,sta[N],las[N];
ll suf[N],pre[N];

int mx[N<<2];

void build(int now ,int l,int r) {
    if(l ==r ) {
        mx[now] = a[l];
        rt;
    }
    int mid = l + r >> 1;
    build(now << 1,l,mid);
    build(now<<1|1,mid+1,r);
    mx[now] = max(mx[now<<1],mx[now<<1|1]);
}

int query_max(int now,int l,int r,int ml,int mr) {
    if(ml <= l && mr <= r) return mx[now];
    if(ml > r || mr < l) return 0;
    int mid = l + r >> 1;
    return max(query_max(now<<1,l,mid,ml,mr),query_max(now<<1|1,mid+1,r,ml,mr));
}

int query_pos(int now,int l,int r,int ml,int mr,int val) {
    if(l == ml && r == mr) {
        if(mx[now] < val) return -1;
        if(l == r) return 1;
        int mid = l + r>> 1;
        if(mx[now*2] == val) {
            return query_pos(now * 2,l,mid,l,mid,val);
        } else {
            return query_pos(now * 2 + 1,mid + 1,r,mid+1,r,val);
        }
    }
    int mid = l + r >> 1;
    if(mr <= mid) {
        return query_pos(now<<1,l,mid,ml,mr,val);
    } else if(mr > mid) {
        return query_pos(now<<1|1,mid+1,r,ml,mr,val);
    } else {
        int res = query_pos(now<<1,l,mid,ml,mid,val);//如果左半边没有 
        if(res == -1) {
            res = query_pos(now * 2 + 1,mid+1,r,mid+1,mr,val);
        }
        return res;
    }
}
void solve()
{
//    cin>>n>>m;
    cin>>n>>q;
    pre[0] = 0;
    fo(i,1,n) {
        cin>>a[i];
        pre[i] = pre[i-1] + a[i];
    }
    top = 0;
    sta[++top] = n + 1;
    a[n+1] = inf;
    of(i,n,1) {
        while(top > 0 && a[sta[top]] < a[i]) { 
            -- top;
        }
        las[i] = sta[top];
        sta[++top] = i;
    }
    suf[n+1] = 0;
    of(i,n,1) {
        suf[i] = suf[las[i]] + 1ll * a[i] * (pre[las[i] - 1] - pre[i-1]);
    }
    build(1,1,n);
    fo(i,1,q) {
        int l,r;cin>>l>>r;
        ll ans = suf[l];
        int maxx = query_max(1,1,n,l,r);
        int pos = query_pos(1,1,n,l,r,maxx);
        ans -= suf[las[pos]];
        ans -= 1ll * maxx * (pre[las[pos] - 1] - pre[r]);
        cout<<ans<<endl;
    }
}

 

标签:tmp,int,pos,初赛,yy,xx,之星,第三场,fo
来源: https://www.cnblogs.com/er007/p/16655712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有