首页 > 其他分享 >CF685E 题解

CF685E 题解

时间:2024-07-29 10:33:37浏览次数:6  
标签:node int 题解 询问 rd CF685E include 联考

吐槽一下,为啥这道题 \(\mathcal{O}(nm)\) 可以过。联考的时候做到了这道题,还一直在想更快的算法。。。

然后,这联考的数据是自己出的,有 \(s=t\) 的情况,我反正是完全没有想到,又因为是捆绑测试,直接痛失 \(100pts\)。


首先考虑转化一下题目。对于一个询问 \(l,r,s,t\),就相当于是让你从第 \(l\) 到 \(r\) 条边中选出一些边,使得依次按这些边走可以从 \(s\) 到 \(t\)。

先考虑只有这一个询问的情况。我们可以令数组 \(a_{i,j}\) 表示 \(i\) 能否到达 \(j\),然后按顺序枚举第 \(l\) 到 \(r\) 条边。设现在这条边是 \(u,v\),考虑应该更新哪些值。可以发现如果有一个点 \(x\) 能到达 \(u\),那么将 \(u,v\) 这条边加进来之后 \(x\) 就也能到达 \(v\) 了。所以如果 \(a_{x,u}=1\) 或 \(a_{x,v}=1\),那么就应该更新 \(a_{x,v}=1\) 或 \(a_{x,u}=1\),简化一下就是对于所有 \(1\le x\le n\),\(a_{x,u} = a_{x,v} = a_{x,u}|a_{x,v}\)。

现在是多组询问,我们可以将询问按 \(r\) 排一遍序,然后还是依次枚举每一条边,每次更新所有 \(r\) 为当前边的询问。

但是每个询问还有 \(l\) 的限制,所以 \(a\) 数组就不能只单纯地记 \(0\) 和 \(1\) 了,而应该记一个数 \(x\)。\(a_{i,j}=x\) 就表示从 \(i\) 到 \(j\) 的所有路径中第一条边编号最大能是多少,这样子如果 \(a_{s,t}\ge l\),那就说明询问是可以做到的,而转移的时候只需要把 \(a_{x,u}|a_{x,v}\) 改成 \(\max({a_{x,u},a_{x,v}})\) 即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 1005,M = 2e5+5,Q = 1e6+5;
int a[N][N],e[M][2],n,m,q;
bool ans[Q];
struct node{int l,r,s,t,id;}que[Q];
bool cmp(node x,node y){return x.r < y.r;}
inline int rd()
{
    char c;int f = 1;
    while(!isdigit(c = getchar()))if(c=='-')f = -1;
    int x = c-'0';
    while(isdigit(c = getchar()))x = x*10+(c^48);
    return x*f;
}
int main()
{
	n = rd();m = rd();q = rd();
	for(int i = 1;i <= m;i++)
		e[i][0] = rd(),e[i][1] = rd();
	for(int i = 1;i <= q;i++)
		que[i] = {rd(),rd(),rd(),rd(),i};
	sort(que+1,que+q+1,cmp);int now = 1;
	for(int i = 1;i <= m;i++)
	{
		int u = e[i][0],v = e[i][1];
		a[u][u] = i;a[v][v] = i;
		for(int j = 1;j <= n;j++)
			a[j][u] = a[j][v] = max(a[j][u],a[j][v]);
		for(node x;now <= q&&(x = que[now]).r <= i;now++)
			ans[x.id] = a[x.s][x.t] >= x.l;
	}
	for(int i = 1;i <= q;i++)puts(ans[i]?"Yes":"No");
    return 0;
}

标签:node,int,题解,询问,rd,CF685E,include,联考
From: https://www.cnblogs.com/max0810/p/18329534

相关文章

  • P4468[SCOI2007]折纸-题解
    题意:有一个左下角为\((0,0)\),右上角为\((100,100)\)的正方形,给你\(n\)个有向线段和\(m\)个询问,将纸片依次按直线折叠,然后每次询问让你求出某个点上有多少层纸。分析:观察到数据范围非常小,于是可以直接对于每个询问\(\mathcal{O}(2^n)\)来求。具体的,对于每一个点,倒着枚......
  • P8540 「Wdoi-2」夜空中的 UFO 恋曲 题解
    hanghangakioi考试的时候在乱猜结论,交了几遍就过了,证明当然是赛后才想的()文中加粗部分是需要读者稍微思考一下原因的地方(不是重点)。先考虑一下样例二,将\(10^{18}\)化成二进制:\(1101...001000000000000000000\)。其实只需要知道末尾有\(18\)个\(0\)就行了,因为在\(x\)......
  • CF1906C Cursed Game 题解
    题目大意交互库有一个\(3\times3\)的01矩阵\(a\),每次询问一个\(n\timesn\)的01矩阵\(b\),交互库会返回一个\((n-2)\times(n-2)\)的01矩阵\(c\),满足:\[c_{x,y}=\bigoplus\limits_{1\lei,j\le3}\left(a_{i,j}\operatorname{AND}b_{x+i-1,y+j-1}\right......
  • 梦熊十三连测第三场题解
    T1本题考察了数论的相关知识。30pts暴力枚举每次洗牌的情况,时间复杂度为\(O(n^2)\)。60pts首先卡牌\(1\)和\(2n\)一直不动,可以不用考虑这两张牌。将位置和剩下的牌上的数字全减\(1\),那么数字为\(k\)的牌操作一次后就会到\(2k\bmod(2n-1)\)的位置。那么问题相当......
  • Maximum Glutton题解
    正常动规,但是赛时死了。分析看到\(n\)很小,但是\(X\)和\(Y\)有点大,所以状态稍微改变一下。设\(dp_{i,j}\)表示已经选到第\(j\)个,且甜度为\(i\)时咸度的最小值。转移方程为:\[dp_{j,k}=\min_{0\lek\lei,a_i\lej\leX}(dp_{j,k},dp_{j-a_i,k-1}+b_i)\]按照\(i,j......
  • CF526G Spiders Evil Plan 题解
    Description给定一棵\(n\)个节点的无根树,每条边有边权。有\(q\)次询问,每次询问给出\(x,y\),你需要选择\(y\)条树上的路径,使这些路径形成一个包含\(x\)的连通块,且连通块中包含的边权和最大。\(n,q\le10^5\),强制在线。Solution考虑只有一组询问怎么快速求答案。容......
  • 【科大讯飞笔试题汇总】2024-07-27-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • ABC364 DEF 题解
    ABC364DEF题解D-K-thNearest题目链接赛时想了一个(也许确实是对的)做法,但是代码太难写,一直没写出来……看了官方题解才发现正解其实也很简单……本题最关键的一点是要转换思路:与其考虑“离某个点第\(k\)近的点在哪”,不如考虑“离某个点距离不超过\(x\)的点有多少个”。......
  • 会员购项目面试题解析:高效数据抓取与异常处理
    会员购项目亮点日志记录信息协程异步抓取数据,大大提高抓取速度捕获异常,并添加重试机制源码importloggingimporttimeimportrequestsimportasyncioimportaiohttpfromaiohttpimportContentTypeErrorimportcsv#配置日志logging.basicConfig(level=logging......
  • C++题解(17) 狐猬编程: 640.线段覆盖
    题目描述在一条数轴上,有N条线段,第i条线段的左端点是s[i],右端点是e[i]。如果线段有重叠(即使是端点重叠也算是重叠),则输出“impossible”,如果没有重叠则输出“possible”。输入格式输入文件名:640.in多组测试数据。第一行,一个整数G,表示有G组测试数据。1<=G<=10。每组......