zoukankan      html  css  js  c++  java
  • Conveyor Belts

    这题目还是比较神仙的

    不知道如何老师不提示应该怎么想到

    反正老师这节课就讲分块,。。。emm

    首先m的数据范围很小,这给了我们希望

    发现没有down这个指令(我打不出来qaq),所以产生 (loop) 的唯一可能是连续的'><'

    对行进行分块,首先预处理出每个位置能够走到哪里,时间复杂度 (O(NM))

    修改只需要将该块的元素能够走到的位置全部改一遍就行了

    查询,emm直接跑就行了

    具体实现见代码

    // By Hacheylight
    
    #include <map>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <vector>
    #include <bitset>
    #include <cstdio>
    #include <cctype>
    #include <string>
    #include <numeric>
    #include <cstring>
    #include <cassert>
    #include <climits>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std ;
    //#define int long long
    #define rep(i, a, b) for (int i = (a); i <= (b); i++)
    #define per(i, a, b) for (int i = (a); i >= (b); i--)
    #define loop(it, v) for (auto it = v.begin(); it != v.end(); it++)
    #define cont(i, x) for (int i = head[x]; i; i = e[i].nxt)
    #define clr(a) memset(a, 0, sizeof(a))
    #define ass(a, sum) memset(a, sum, sizeof(a))
    #define lowbit(x) (x & -x)
    #define all(x) x.begin(), x.end()
    #define SC(t, x) static_cast <t> (x)
    #define ub upper_bound
    #define lb lower_bound
    #define pqueue priority_queue
    #define mp make_pair
    #define pb push_back
    #define pof pop_front
    #define pob pop_back
    #define fi first
    #define se second
    #define y1 y1_
    #define Pi acos(-1.0)
    #define iv inline void
    #define enter cout << endl
    #define siz(x) ((int)x.size())
    #define file(x) freopen(x".in", "r", stdin),freopen(x".out", "w", stdout)
    typedef long double ld ;
    typedef long long ll ;
    typedef unsigned long long ull ;
    typedef pair <int, int> pii ;
    typedef pair <ll, int> pli ;
    typedef pair<int, pii> tri ;
    typedef vector <int> vi ;
    typedef vector <pii> vii ;
    typedef vector <vi> vvi ;
    typedef queue <int> qi ;
    typedef queue <pii> qii ;
    typedef set <int> si ;
    typedef map <int, int> mii ;
    typedef map <string, int> msi ;
    const int N = 100010 ;
    const int M = 15 ;
    const int K = 320 ;
    const int INF = 0x3f3f3f3f ;
    const int iinf = 1 << 30 ;
    const ll linf = 2e18 ;
    const int mod = 1000000007 ;
    const double eps = 1e-7 ;
    void douout(double x){ printf("%lf
    ", x + 0.0000000001) ; }
    template <class T> void print(T a) { cout << a << endl ; exit(0) ; }
    template <class T> void chmin(T &a, T b) { if (a > b) a = b ; }
    template <class T> void chmax(T &a, T b) { if (a < b) a = b ; }
    void add(int &a, int b) { a = a + b < mod ? a + b : a + b - mod ; }
    void sub(int &a, int b) { a = (a - b + mod) % mod ; }
    void mul(int &a, int b) { a = (ll) a * b % mod ; }
    int addv(int a, int b) { return (a += b) >= mod ? a -= mod : a ; }
    int subv(int a, int b) { return (a -= b) < 0 ? a += mod : a ; }
    int mulv(int a, int b) { return (ll) a * b % mod ; }
    int read() {
        int f = 1, x = 0 ;
        char ch = getchar() ;
        while (!isdigit(ch)) { if (ch == '-') f = -1 ; ch = getchar() ; }
        while (isdigit(ch)) { x = x * 10 + ch -'0' ; ch = getchar() ; }
        return x * f ;
    }
    int pw(int a, int b) {
        int s = 1 ;
        for (; b; b >>= 1, a = (ll) a * a % mod)
        if (b & 1) s = (ll) s * a % mod ;
        return s ;
    }
    
    int n, m, q, len, num ;
    int l[K], r[K], bl[N] ;
    int dp[N][M] ;
    char s[N][M] ;
    
    void build() {
    	len = sqrt(n), num = (n - 1) / len + 1 ;
    	rep(i, 1, n) bl[i] = (i - 1) / len + 1 ;
    	rep(i, 1, num) l[i] = (i - 1) * len + 1, r[i] = i * len ;
    	r[num] = n ;
    }
    
    int dfs(int x, int y) {
    	if (dp[x][y]) return dp[x][y] ;
    	if (s[x][y] == '^') {
    		int tx = x - 1, ty = y ;
    		if (tx < l[bl[x]]) dp[x][y] = tx * (m + 2) + ty ;
    		else dp[x][y] = dfs(tx, ty) ;
    	} 
    	if (s[x][y] == '>') {
    		int tx = x, ty = y + 1 ;
    		if (ty == m + 1) dp[x][y] = tx * (m + 2) + ty ;
    		else if (s[tx][ty] == '<') dp[x][y] = dp[tx][ty] = -1 ;
    		else dp[x][y] = dfs(tx, ty) ;
    	}
    	if (s[x][y] == '<') {
    		int tx = x, ty = y - 1 ;
    		if (ty == 0) dp[x][y] = tx * (m + 2) + ty ;
    		else if (s[tx][ty] == '>') dp[x][y] = dp[tx][ty] = -1 ;
    		else dp[x][y] = dfs(tx, ty) ;
    	} 
    	return dp[x][y] ;
    }
    
    void block(int id) {
    	rep(i, l[id], r[id]) 
    	rep(j, 1, m)
    	dfs(i, j) ;
    }
    
    void modify(int x, int y, char c) {
    	rep(i, l[bl[x]], r[bl[x]])
    	rep(j, 1, m)
    	dp[i][j] = 0 ;
    	s[x][y] = c ;
    	block(bl[x]) ;
    }
    
    int query(int x, int y) {
    	if (dp[x][y] == -1) return -1 ;
    	if (bl[x] == 1) return dp[x][y] ; // 第一行 
    	int tx = dp[x][y] / (m + 2), ty = dp[x][y] % (m + 2) ;
    	if (ty == 0 || ty == m + 1) return dp[x][y] ;
    	return query(tx, ty) ;	
    }
    
    signed main() {
    	scanf("%d%d%d", &n, &m, &q) ;
    	rep(i, 1, n) scanf("%s", s[i] + 1) ;
    	build() ;
    	rep(i, 1, num) block(i) ; 
    	while (q--) {
    		int x, y ; string op, ch ; cin >> op ;
    		if (op[0] == 'A') {
    			scanf("%d%d", &x, &y) ;
    			int pos = query(x, y) ;
    			if  (pos == -1) puts("-1 -1") ;
    			else printf("%d %d
    ", pos / (m + 2), pos % (m + 2)) ;
    		} else {
    			scanf("%d%d", &x, &y) ; cin >> ch ;
    			modify(x, y, ch[0]) ;
    		}
    	}
    	return 0 ;
    }
    
    
    
  • 相关阅读:
    PostgreSQL数据库中的常见错误
    postgresql相关命令
    Linux系统查看公网IP地址
    TCP/IP TIME_WAIT状态原理
    TCP连接状态详解及TIME_WAIT过多的解决方法
    让你提升命令行效率的 Bash 快捷键 [完整版]
    linux 如何显示一个文件的某几行(中间几行)
    linux中内核的一个不错的参数somaxconn
    Linux crontab 实现每秒执行
    Linux tar This does not look like a tar archive
  • 原文地址:https://www.cnblogs.com/harryhqg/p/Conveyor-Belts.html
Copyright © 2011-2022 走看看