cf232E. Quick Tortoise(分治 bitset dp)

题意

题目链接

Sol

感觉这个思路还是不错的

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 501, SS = 5e6 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, Q, ans[SS];
char s[MAXN][MAXN];
bitset<MAXN> f[MAXN][MAXN], g[MAXN][MAXN], Empty;
struct Query {
    int x1, y1, x2, y2, id;
}q[SS];
void solve(int l, int r, vector<Query> q) {
    if(l > r) return ;
    vector<Query> lq, rq;
    int mid = l + r >> 1;
    //f[i][j]从i,j能到达的mid中的点集
    //g[i][j]从mid能到达i, j的点集
    for(int i = mid; i >= l; i--) {
        for(int j = M; j >= 1; j--) {
            f[i][j] = Empty;
            if(i == mid) f[i][j][j] = (s[i][j] == '.');
            if(i + 1 <= mid && s[i + 1][j] == '.') f[i][j] = f[i][j] | f[i + 1][j];
            if(j + 1 <= M && s[i][j + 1] == '.') f[i][j] = f[i][j] | f[i][j + 1];

        }
    }
    for(int i = mid; i <= r; i++) {
        for(int j = 1; j <= M; j++) {
            g[i][j] = Empty;
            if(i == mid) g[i][j][j] = (s[i][j] == '.');
            if(i - 1 >= mid && s[i - 1][j] == '.') g[i][j] = g[i][j] | g[i - 1][j];
            if(j - 1 >= 1 && s[i][j - 1] == '.') g[i][j] = g[i][j] | g[i][j - 1];
        }
    }
    for(auto &cur : q) {
        if(cur.x2 < mid) lq.push_back(cur);
        else if(cur.x1 > mid) rq.push_back(cur);
        else {
            //cout << f[cur.x1][cur.y1] << endl;
            //cout << g[cur.x2][cur.y2] << endl;
            ans[cur.id] = (f[cur.x1][cur.y1] & g[cur.x2][cur.y2]).count();
        }
    }
    solve(l, mid - 1, lq);
    solve(mid + 1, r, rq);
}
int main() {
    N = read(); M = read();
    for(int i = 1; i <= N; i++) scanf("%s", s[i] + 1);
    Q = read();
    vector<Query> now;
    for(int i = 1; i <= Q; i++) {
        q[i].x1 = read(), q[i].y1 = read(), q[i].x2 = read(), q[i].y2 = read(); q[i].id = i;
        now.push_back(q[i]);
    }
    solve(1, N, now);
    for(int i = 1; i <= Q; i++) puts(ans[i] ? "Yes" : "No");
    return 0;
}
/*
3 3
...
.##
.#.
1
1 1 3 1

3 3
...
.##
.#.
5
1 1 3 3
1 1 1 3
1 1 3 1
1 1 1 2
1 1 2 1
*/

原文地址:https://www.cnblogs.com/zwfymqz/p/10273942.html

时间: 2024-10-14 06:18:41

cf232E. Quick Tortoise(分治 bitset dp)的相关文章

CF232E Quick Tortoise , Fzoj 3118

这一题由于数据较多,我们考虑离线处理. 分治.对于两个点s,t,如果起点在mid这条横线上方,终点在下方,那么它必定会穿过mid这条线.所以只要s可以到mid上一点x,x可以到t,st就是安全的. 用bitset维护.设\(f1[i][j]\)为上方ij到mid这条线的是否可以的01值,\(f2[i][j]\)为下方ij到mid的01值.将f1[sx][sy]&f2[tx][ty],如果结果存在1,那么就能走到. Codeforces版本 #include <cstdio> #incl

挖坑#3-----DP优化+CDQ分治+期望DP

1492: [NOI2007]货币兑换Cash 1176: [Balkan2007]Mokia 1452: [JSOI2009]Count 1563: [NOI2009]诗人小G tyvj1309  刷题的玖君 3036: 绿豆蛙的归宿 1076: [SCOI2008]奖励关 1415: [Noi2005]聪聪和可可 1444: [Jsoi2009]有趣的游戏 2337: [HNOI2011]XOR和路径 3586: 字符串生成器 记得还有的啊... 挖坑#3-----DP优化+CDQ分治+期望

CodeForces 232E.Quick Tortoise

John Doe has a field, which is a rectangular table of size n × m. We assume that the field rows are numbered from 1 to n from top to bottom, and the field columns are numbered from 1 to m from left to right. Then the cell of the field at the intersec

Codeforces 789e The Great Mixing (bitset dp 数学)

Sasha and Kolya decided to get drunk with Coke, again. This time they have k types of Coke. i-th type is characterised by its carbon dioxide concentration . Today, on the party in honour of Sergiy of Vancouver they decided to prepare a glass of Coke

BZOJ3163&amp;Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]

3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 428  Solved: 277[Submit][Status][Discuss] Description “寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听.”失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的感觉,却不能回忆起她的音容笑貌. 记忆中,她总是喜欢给Eden出谜题:在 valent

Loj515 「LibreOJ β Round #2」贪心只能过样例 - Bitset,Dp

bitset的基本应用了 类似可行性背包的dp考虑 复杂度O(nmL/64) 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 bitset <1000005> bs,bs0; 5 6 int n,a,b; 7 8 int main(){ 9 ios::sync_with_stdio(false); 10 cin>>n; 11 bs[0]=1; 12 for(int i=1;i<=n;i++){ 13 bs

HDU - 6268: Master of Subgraph (分治+bitset优化背包)

题意:T组样例,给次给出一个N节点的点权树,以及M,问连通块的点权和sum的情况,输出sum=1到M,用0或者1表示. 思路:背包,N^2,由于是无向的连通块,所以可以用分治优化到NlgN. 然后背包可以用bitset优化.注意不要想着背包合并背包,背包只能合并单点. #include<bits/stdc++.h> #define pb push_back #define rep(i,a,b) for(int i=a;i<=b;i++) #define Gv G[u][i] #defin

hdu 6268 Master of Subgraph(点分治+bitset)

You are given a tree with n nodes. The weight of the i-th node is wi. Given a positive integer m, now you need to judge that for every integer i in [1,m] whether there exists a connected subgraph which the sum of the weights of all nodes is equal to

暴力+分治+贪心+DP:最大子序列和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6 暴力:暴力列举所有可能的连续子数组,算法复杂度O(N^3)算法1: 1 int MaxSubseqSum1(int A[], int N) 2 { 3 int ThisSum, MaxSum = 0; 4 int i,j,k; 5 6 for (i = 0;