其他分享
首页 > 其他分享> > 百度之星初赛第三场 2 4 6

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

作者:互联网

感觉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