【题解】CF575I Robots Protection

CF 官网链接 CF.ML 链接

  • \(N \le 5000, Q \le 10^5\)
  • \(N \le 3 \times 10^5, Q \le 3 \times 10^5\)

思路

这是一道二维数点题。

只考虑 \(dir = 1\),记一个三角形直角顶点 \((p, q)\) ,直角边长 \(r\)

考虑斜边的限制,斜边的方程是 \(x + y = p + q + r\)

所以如果一个三角形对询问有贡献,记询问点 \((x, y)\) ,则\(x + y \in [p + q, p + q + r]\)

同时 \((p, q)\) 在 \((x, y)\) 左下角,有 \(p \le x,q \le y\)

所以这是个三维数点?这样是很浪费的,既然限制了 \(x + y\) 还要同时限制 \(x, y\) 两维,没什么用。

发现不可能同时有 \(p > x, q > y\),那么两维就是独立的,可以容斥计算出来。

分别统计 \(p \le x, q \le y\) 的数量,这样满足两个条件的被算了两次,不满足条件的算了一次,再减去满足第一个条件的点的总数,就可以了。

对于第一个条件,写分治的话就归并维护 \(\ge p + q\) ,再维护一个优先队列,维护 \(\le p + q + r\) 即可,其实写树套树除了常数大码量大也没什么缺点,当然原来的数据范围写二维树状数组就好。

然后将图旋转 \(4\) 次即可。

\(\mathcal O(N \log^2 N)\)

Code

旋转的时候 \(N,Q\) 写反了,调了 2h...

下次变量名还是写准确点吧。

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cassert>
using namespace std;
#define File(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
typedef long long ll;
namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	char getc () {return gc();}
	inline void flush () {fwrite (obuf, 1, oS - obuf, stdout); oS = obuf;}
	inline void putc (char x) {*oS ++ = x; if (oS == oT) flush ();}
	template <class I> inline void gi (I &x) {for (f = 1, c = gc(); c < ‘0‘ || c > ‘9‘; c = gc()) if (c == ‘-‘) f = -1;for (x = 0; c <= ‘9‘ && c >= ‘0‘; c = gc()) x = x * 10 + (c & 15); x *= f;}
	template <class I> inline void print (I x) {if (!x) putc (‘0‘); if (x < 0) putc (‘-‘), x = -x;while (x) qu[++ qr] = x % 10 + ‘0‘,  x /= 10;while (qr) putc (qu[qr --]);}
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi; using io :: putc; using io :: print; using io :: getc;
template<class T> void upmax(T &x, T y){x = x>y ? x : y;}
template<class T> void upmin(T &x, T y){x = x<y ? x : y;}
const int N = 300005;
int bit[N];
int n;
struct BIT{
	int tr[N];
	void modify(int p, int v){
		for(; p<=n; p += p & -p) tr[p] += v;
	}
	int query(int p){
		int s = 0;
		for(; p; p ^= (p & -p)) s += tr[p];
		return s;
	}
}Tx, Ty;

const int dirMap[] = {0, 0, 1, 3, 2};

struct Query{
	int d, x, y, r;
}tq[N], q[N], tp[N];

void rotateMap(int Q){
	for(int i=1; i<=Q; i++){
		int tx, ty;
		tx = tq[i].y; ty = n + 1 - tq[i].x;
		tq[i].x = tx; tq[i].y = ty;
		if(tq[i].d != 4) tq[i].d = (tq[i].d + 1) % 4;
	}
}

int res[N];

struct Elem{
	int x, y, v;
	Elem(int _x, int _y, int _v) : x(_x), y(_y), v(_v) {}
	inline bool operator<(const Elem &rhs) const {return v > rhs.v;} // min heap
};
void solve(int l, int r){
	if(l >= r) return ;
	int mid = (l + r) >> 1;
	solve(l, mid); solve(mid + 1, r);
	priority_queue<Elem> act;
	int p = l, pt = 0, cnt = 0;
	for(int i=mid+1; i<=r; i++){
		while(p <= mid && q[p].x + q[p].y <= q[i].x + q[i].y){
			if(q[p].d == 0){
				Elem e(q[p].x, q[p].y, q[p].x + q[p].y + q[p].r);
				act.push(e); ++cnt;
				Tx.modify(e.x, 1); Ty.modify(e.y, 1);
			}
			tp[pt++] = q[p++];
		}
		if(q[i].d == 4){
			while(!act.empty() && act.top().v < q[i].x + q[i].y){
				Elem e = act.top();
				--cnt;
				Tx.modify(e.x, -1); Ty.modify(e.y, -1);
				act.pop();
			}
			res[q[i].r] += Tx.query(q[i].x) + Ty.query(q[i].y) - cnt;
		}
		tp[pt++] = q[i];
	}
	while(!act.empty()){
		Elem e = act.top(); act.pop();
		Tx.modify(e.x, -1); Ty.modify(e.y, -1);
	}
	while(p <= mid) tp[pt++] = q[p++];
	copy_n(tp, r - l + 1, q + l);
}

int main(){
	int Q;
	gi(n); gi(Q);
	int ansc = 0;
	for(int i=1; i<=Q; i++){
		int opt; gi(opt);
		if(opt == 2){
			gi(tq[i].x); gi(tq[i].y);
			tq[i].d = 4; tq[i].r = ++ansc;
		}
		else{
			gi(tq[i].d); gi(tq[i].x); gi(tq[i].y); gi(tq[i].r);
			tq[i].d = dirMap[tq[i].d];
		}
	}
	for(int i=0; i<4; i++){
		int qc = 0;
		for(int i=1; i<=Q; i++)
			if(tq[i].d == 0 || tq[i].d == 4) q[++qc] = tq[i];
		solve(1, qc);
		rotateMap(Q);
	}
	for(int i=1; i<=ansc; i++) print(res[i]), putc(‘\n‘);
	return 0;
}

原文地址:https://www.cnblogs.com/RiverHamster/p/sol-cf575i.html

时间: 2024-10-10 10:33:58

【题解】CF575I Robots Protection的相关文章

Bubble Cup 8 finals I. Robots protection

题意: 有一个正方形区域, 要求支持两个操作: 1.放置三角形,给定放置方向(有4个方向,直角边与坐标轴平行),直角顶点坐标,边长 2.查询一个点被覆盖了多少次 1<=正方形区域边长n<=5000 1<=询问数<=10^5 保证输入合法,三角形被正方形区域完全包含. 题解: 嗯这是一道数据结构题… 一开始我想起来之前做过但没做出来的一道三角形修改三角形查询的分块题… 然后…GEOTCBRL说,是k-d tree呀,CF上面有标程代码长度限制的… 然而我并不会用k-d tree做这个

【题解】CF24D Broken Robots(收敛性)

[题解]CF24D Broken Robots http://codeforces.com/problemset/problem/24/D 解1 获得一个比较显然的转移式子 \(dp(i,j)\)代表在\((i,j)\)坐标需要期望的走的次数 \[ dp(i,j)=0.25(1+dp(i-1,j)+dp(i,j-1)+dp(i,j+1)) \] 然而我们可以发现这个式子不满足无后效性..也找不到一种合适的顺序DP. 我们发现可以高斯消元,但是\(O(n^4)\)的复杂度我们接受不了. 式子里面的

【题解】CF#24 D-Broken Robots

在某次考试的时候用过的办法,懒人必备……[笑哭] 一个非常显然的 dp,我们用 \(f[i][j]\) 表示第 \(i\) 行第 \(j\) 列的格子走到最后一排的期望步数转移即为 \(f[i][j] = \frac{f[i][j - 1] + f[i][j + 1] + f[i + 1][j] + f[i][j]}{4} + 1\) 略微的化一下简: \(f[i][j] = \frac{f[i][j - 1] + f[i][j + 1] + f[i + 1][j] + 4}{3}\) (当然,

2016 ccpc 网络选拔赛 F. Robots

Robots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 60    Accepted Submission(s): 13 Problem Description QXJ has N robots on the plane, the i-th is at (xi,yi), numbereded 1 to N. Every robot

codeforces ~ 1004 C Sonya and Robots (dp)

C. Sonya and Robots time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Since Sonya is interested in robotics too, she decided to construct robots that will read and recognize numbers. Sonya ha

The Preliminary Contest for ICPC Asia Nanjing 2019/2019南京网络赛——题解

(施工中……) 比赛传送门:https://www.jisuanke.com/contest/3004 D. Robots(期望dp) 题意 给一个DAG,保证入度为$0$的点只有$1$,出度为$0$的点只有$n$. 现在一个机器人从$1$出发,每天都会以相同的概率前往相邻节点之一或静止不动. 每天机器人消耗的耐久等于经过的天数. 求机器人到点$n$期望消耗的耐久. 划水划的很愉快,唯一一道做出来的题.但是和题解做法不同(感觉我的方法麻烦),因此砸了3h在这题上面(正在试图读懂题解ing). 设

D题 Robots 【期望】

Robots Given a directed graph with no loops which starts at node 11 and ends at node nn.There is a robot who starts at 11, and will go to one of adjacent nodes or stand still with equal probability every day.Every day the robot will have durability c

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了