首页 > 其他分享 >C137 线段树分治 P2147 [SDOI2008] 洞穴勘测

C137 线段树分治 P2147 [SDOI2008] 洞穴勘测

时间:2024-06-11 18:34:32浏览次数:9  
标签:P2147 C137 include int siz top solve mp SDOI2008

视频链接:

 

P2147 [SDOI2008] 洞穴勘测 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 线段树分治 O(mlogmlogm)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
const int N=200005;
int n,m,top,ans[N];
int p[N],siz[N]; //并查集
struct node{
  int x,y;
}st[N]; //栈
struct Q{
  int x,y,b; //b=1是查询,b=0不是
  bool operator<(const Q &a)const{
    return x==a.x?y<a.y:x<a.x;
  }
}q[N]; //操作
vector<Q>tr[N<<2]; //节点
map<Q,int> mp;     //操作信息<<x,y,b>,i>

void insert(int u,int l,int r,int L,int R,Q q){
  if(l>R||r<L) return;
  if(L<=l&&r<=R) return tr[u].push_back(q);
  insert(ls,l,mid,L,R,q);
  insert(rs,mid+1,r,L,R,q);
}
int find(int x){ //查找根
  return p[x]==x?x:find(p[x]);
}
void merge(int x,int y){ //合并集合
  x=find(x),y=find(y);
  if(x==y) return;
  if(siz[x]>siz[y]) swap(x,y);
  st[++top]={x,y};
  p[x]=y;
  siz[y]+=siz[x];
}
void solve(int u,int l,int r){
  int now=top;
  for(auto i:tr[u]) merge(i.x,i.y);
   
  if(l==r){
    if(q[l].b) ans[l]=find(q[l].x)==find(q[l].y);
  }
  else solve(ls,l,mid),solve(rs,mid+1,r);
  
  while(top>now){ //撤销合并
    node t=st[top--];
    p[t.x]=t.x;
    siz[t.y]-=siz[t.x];
  }
}
int main(){
  scanf("%d%d",&n,&m); char op[9];
  for(int i=1;i<=n;i++) p[i]=i,siz[i]=1;
  for(int i=1,x,y;i<=m;i++){
    scanf("%s%d%d",op,&x,&y);
    if(x>y) swap(x,y); //保证映射唯一
    if(op[0]=='C'){
      q[i]={x,y,0};
      mp[q[i]]=i;  //记录边q[i]的出现时刻
    }
    else if(op[0]=='D'){
      q[i]={x,y,0};
      insert(1,1,m,mp[q[i]],i,q[i]);//插入q[i]的出现时间
      mp.erase(q[i]); //删除边q[i]
    }
    else q[i]={x,y,1}; //q[i]是查询
  }
  for(auto i:mp) //插入每条边的出现时间
    insert(1,1,m,i.second,m,i.first);
  solve(1,1,m);
  for(int i=1;i<=m;i++)if(q[i].b)puts(ans[i]?"Yes":"No");
}

 

标签:P2147,C137,include,int,siz,top,solve,mp,SDOI2008
From: https://www.cnblogs.com/dx123/p/18239902

相关文章

  • [SDOI2008] Sue 的小球 题解
    题目描述首先将彩蛋按照横坐标从小到大排序,依次标号为\(1\simn\)。显然,\(Sue\)走过一段时间后,走过的点一定属于一段连续区间。所以本题采用区间\(dp\)。不妨先做一个简单转化,由于每个彩蛋初始高度确定,若想让总分最高,就要使扣分最少。所以下面的\(dp\)从扣分最少入手。设......
  • P2155 [SDOI2008] 沙拉公主的困惑
    关于题目题目描述大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于数量可能非常大,你......
  • 解题报告 洛谷P2155 [SDOI2008] 沙拉公主的困惑
    P2155[SDOI2008]沙拉公主的困惑题目题面非常的简洁,求\(\sum\limits_{i=1}^{n!}[i\perpm!]\)直接颓式子,\[\begin{aligned}ans&=\dfrac{n!}{m!}\cdot\varphi(m!)\\\\&=\dfrac{n!}{m!}*m!\prod\limits_{p\midm!}[\dfrac{p-1}{p}]\\&=n!\cdot\dfrac{\......
  • arc136,arc137,arc138题解
    ARC136A-EAA↔BB贪心。可以把BB换成A,可以把BA换成AB。BTripleShift直观上觉得只要数集相同,那么就是可以变换的。大概方法就是每次找到正确的数把它挪到数列的端点,这样显然是可行的。但是在相反的三个上出现了问题,原因在于只剩最后两个数时方向可能是反着的。分析......
  • ARC137D Prefix XORs 题解
    这里的所有下标从\(\bm0\)开始。我们考察一下每次操作后的数列\(a\)会是什么样的。这里用\(a_i\)前面的系数\(x\)表示\(a_i\)贡献了\(x\)次,\(+\)表示异或。\[\begin{matrix}k=0&a_0&a_1&a_2&\cdots&a_{n-1}\\k=1&a_0&a_0+a_1&a_0+a_1+a_2&\cdots&......
  • [SDOI2008] 递归数列
    题面一个由自然数组成的数列按下式定义:对于\(i\lek\):\(a_{i}=b_{i}\)。对于\(i>k\):\(\displaystylea_{i}=\sum_{j=1}^{k}{c_{j}\timesa_{i-j}}\)。其中\(b_{1\dotsk}\)和\(c_{1\dotsk}\)是给定的自然数。写一个程序,给定自然数\(m\len\),计算\(\left(\su......
  • bzoj 2049 [Sdoi2008]Cave 洞穴勘测
    2049:[Sdoi2008]Cave洞穴勘测TimeLimit: 10Sec  MemoryLimit: 259MBSubmit: 8714  Solved: 4143[Submit][Status][Discuss]Description辉辉热衷......
  • [SDOI2008] 仪仗队【题解】
    题目描述作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的\(N\timesN\)的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所......
  • 「解题报告」ARC137F Overlaps
    首先有经典结论,两个实数随机变量相等的概率为\(0\)。那么在实数上随机若干个数,最后肯定会有一个顺序关系,而我们只关心这个顺序,所以可以把问题变成离散的。也就是我们现在......
  • BZOJ4698-[sdoi2008] Sandy的卡片
    [sdoi2008]Sandy的卡片时限0.5sSandy和Sue的热衷于收集干脆面中的卡片。然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型。......