• Codeforces Round #539 (Div. 1) 1109F. Sasha and Algorithm of Silence's Sounds LCT+线段树 (two pointers)


    题解请看 Felix-Lee的CSDN博客

    写的很好,不过最后不用判断最小值是不是1,因为[i,i]只有一个点,一定满足条件,最小值一定是1。

    CODE

    写完就A,刺激。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define X first
    #define Y second
    inline void read(int &x) {
        int flag = 1; char ch;
        while(!isdigit(ch=getchar()))if(ch=='-')flag=-flag;
        for(x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
        x*=flag;
    }
    const int MAXN = 1005;
    const int MAXP = 1000005;
    const int INF = 1e9;
    namespace LCT {
    	#define ls ch[x][0]
    	#define rs ch[x][1]
    	int ch[MAXP][2], fa[MAXP];
    	bool rev[MAXP];
    	inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
    	inline bool get(int x) { return ch[fa[x]][1] == x; }
    	inline void mt(int x) { if(rev[x]) rev[x]^=1, rev[ls]^=1, rev[rs]^=1, swap(ls, rs); }
    	void mtpath(int x) { if(!isr(x)) mtpath(fa[x]); mt(x); }
    	inline void rot(int x) {
    		int y = fa[x], z = fa[y]; bool l = get(x), r = l^1;
    		if(!isr(y)) ch[z][get(y)] = x;
    		fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
    		ch[y][l] = ch[x][r]; ch[x][r] = y;
    	}
    	inline void splay(int x) {
    		mtpath(x);
    		for(; !isr(x); rot(x))
    			if(!isr(fa[x])) rot(get(fa[x]) == get(x) ? fa[x] : x);
    	}
    	inline void access(int x) { int y = 0;
    		for(; x; x = fa[y=x]) splay(x), ch[x][1] = y;
    	}
    	inline void bert(int x) { access(x), splay(x), rev[x]^=1; }
    	inline int sert(int x) { access(x), splay(x); for(; ch[x][0]; x=ch[x][0]); return x; }
    	inline void link(int x, int y) { bert(x); if(sert(y) != x) fa[x] = y; }
    	inline void cut(int x, int y) { bert(x); sert(y); fa[x] = ch[y][0] = 0; }
    	inline bool connect(int x, int y) { bert(x); return sert(y) == x; }
    }
    using namespace LCT;
    int n, m, a[MAXN][MAXN], tot;
    #define pii pair<int, int>
    pii pos[MAXP], val[MAXP<<2];
    
    int lz[MAXP<<2];
    inline pii merge(pii A, pii B) {
    	if(A.X < B.X) return A;
    	else if(A.X > B.X) return B;
    	return pii(A.X, A.Y + B.Y);
    }
    inline void upd(int i) { val[i] = merge(val[i<<1], val[i<<1|1]); }
    inline void pd(int i) {
    	if(lz[i]) {
    		val[i<<1].X += lz[i], lz[i<<1] += lz[i];
    		val[i<<1|1].X += lz[i], lz[i<<1|1] += lz[i];
    		lz[i] = 0;
    	}
    }
    void build(int i, int l, int r) {
    	if(l == r) { val[i] = pii(0, 1); return; }
    	int mid = (l + r) >> 1;
    	build(i<<1, l, mid);
    	build(i<<1|1, mid+1, r);
    	upd(i);
    }
    void modify(int i, int l, int r, int x, int y, int v) {
    	if(x <= l && r <= y) { val[i].X += v, lz[i] += v; return; }
    	pd(i);
    	int mid = (l + r) >> 1;
    	if(x <= mid) modify(i<<1, l, mid, x, y, v);
    	if(y > mid) modify(i<<1|1, mid+1, r, x, y, v);
    	upd(i);
    }
    pii query(int i, int l, int r, int x, int y) {
    	if(x <= l && r <= y) return val[i];
    	pd(i);
    	int mid = (l + r) >> 1;
    	pii re = pii(INF, 0);
    	if(x <= mid) re = merge(re, query(i<<1, l, mid, x, y));
    	if(y > mid) re = merge(re, query(i<<1|1, mid+1, r, x, y));
    	return re;
    }
    const int dx[4] = { 0, 0, 1, -1 };
    const int dy[4] = { 1, -1, 0, 0 };
    inline bool chkout(int x, int y) {
    	return x < 1 || y < 1 || x > n || y > m;
    }
    inline bool check(int l, int r) {
    	for(int i = 0; i < 3; ++i) {
    		int x = pos[r].X + dx[i];
    		int y = pos[r].Y + dy[i];
    		if(chkout(x, y) || a[x][y] < l || a[x][y] > r) continue;
    		for(int j = i+1; j < 4; ++j) {
    			int u = pos[r].X + dx[j];
    			int v = pos[r].Y + dy[j];
    			if(chkout(u, v) || a[u][v] < l || a[u][v] > r) continue;
    			if(connect(a[x][y], a[u][v])) return 0;
    		}
    	}
    	return 1;
    }
    inline void del(int l) {
    	for(int i = 0; i < 4; ++i) {
    		int x = pos[l].X + dx[i];
    		int y = pos[l].Y + dy[i];
    		if(chkout(x, y) || !connect(l, a[x][y])) continue;
    		cut(l, a[x][y]);
    	}
    }
    inline void solve(int l, int r) {
    	for(int i = 0; i < 4; ++i) {
    		int x = pos[r].X + dx[i];
    		int y = pos[r].Y + dy[i];
    		if(chkout(x, y) || a[x][y] < l || a[x][y] > r) continue;
    		link(a[x][y], r);
    		modify(1, 1, tot, 1, a[x][y], -1);
    	}
    	modify(1, 1, tot, l, r, 1);
    }
    int main () {
    	scanf("%d%d", &n, &m); tot = n*m;
    	for(int i = 1; i <= n; ++i)
    		for(int j = 1; j <= m; ++j)
    			scanf("%d", &a[i][j]), pos[a[i][j]] = pii(i, j);
    	build(1, 1, tot);
    	LL ans = 0;
    	for(int i = 1, j = 1; i <= tot; ++i) {
    		while(!check(j, i)) del(j++);
    		solve(j, i);
    		ans += query(1, 1, tot, j, i).second;
    	}
    	printf("%I64d
    ", ans);
    }
    
  • 相关阅读:
    mvc使用model进行数据的增加修改的方法
    c#导出word在iis部署上报异常
    做个转圈圈的咚咚
    VS2008中AJAX的部署问题(工具箱中无AJAX Extensions选项卡)
    关于 AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. 错误
    ASP.NET关于继承DropDownList的自定义DDL控件
    线性表顺序表示的C#实现(参考数据结构(C语言版))
    WORD2003出现的乱码
    线性表链式表示的C#实现(参考数据结构(C语言版))
    有错误先找自己的原因(若你百度不出为什么vista开网页慢,可以来试试这方法)
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039271.html
Copyright © 2020-2023  润新知