[luogu3767]膜法

luogu

神仙题

线段树分治+带权并查集

把每个操作看成点

首先这个操作的结构是一棵树

你发现每个点的对它的子树产生影响

我们可以想到用dfn序把它转成一段区间用线段树分治来做

但是还有删除操作,相当于在一个大区间里面挖掉几个小区间

可以对每个操作开一个vector记录区间搞一搞

然后带权并查集是模5意义下的,可以认为给你的操作相当于从u连向v的一条权值为1或2的边

当u,v在同一个集合时,判断是否满足条件,否则就连边

#define pb push_back
#define ls x<<1,l,mid
#define rs x<<1|1,mid+1,r
#include<bits/stdc++.h>
using namespace std;
const int _=1e5+5;
int re(){
int x=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
int n,m,ts,top,dis;
int fa[_],del[_],sz[_],dfn[_],par[_],siz[_],d[_];
bool ans[_];
struct node{int u,v;}st[_];
struct edge{int u,v,w;}e[_];
vector<int>son[_],s[_];
vector<edge>t[_<<2];
void dfs(int u){
sz[u]=1;if(u)dfn[u]=++ts;
if(del[u])s[del[u]].pb(u);
for(int i=0,j=son[u].size();i<j;i++){
int v=son[u][i];
dfs(v);sz[u]+=sz[v];
}
}
void add(int&x,int y){x=(x+y)%5;}
int find(int x){
add(dis,d[x]);
if(x==par[x])return x;
return find(par[x]);
}
void upd(int x,int l,int r,int ql,int qr,edge E){
if(ql<=l&&r<=qr){t[x].pb(E);return;}
int mid=(l+r)>>1;if(ql<=mid)upd(ls,ql,qr,E);
if(qr>mid)upd(rs,ql,qr,E);
}
void solve(int x,int l,int r,bool ok){
int pre=top;
for(int i=0,j=t[x].size();i<j;i++){
int u=t[x][i].u,v=t[x][i].v,w=t[x][i].w;
dis=0;int fu=find(u),du=dis;
dis=0;int fv=find(v),dv=dis;
if(fu==fv&&(du-dv+5)%5!=w)ok=0;
if(fu^fv){
if(siz[fu]>siz[fv]){swap(du,dv);swap(u,v);swap(fu,fv);w=-w;}
siz[fv]+=siz[fu];par[fu]=fv;
d[fu]=(w+dv-du+10)%5;st[++top]=(node){fu,fv};
}
}
if(l==r)ans[l]=ok;
else{int mid=(l+r)>>1;solve(ls,ok);solve(rs,ok);}
while(top^pre){
int u=st[top].u,v=st[top].v;top--;
siz[v]-=siz[u];par[u]=u;d[u]=0;
}
}
int main(){
n=re(),m=re();
int op,u,v;
for(int i=1;i<=m;i++){
son[fa[i]=re()].pb(i);op=re();
if(op==3)del[i]=re();
else{u=re(),v=re();e[i]=(edge){u,v,op};}
}
dfs(0);
for(int i=1;i<=m;i++){
if(del[i])continue;
int k=s[i].size(),lst=dfn[i];
for(int j=0;j<k;j++){
int u=s[i][j];
if(lst<dfn[u])upd(1,1,m,lst,dfn[u]-1,e[i]);
lst=dfn[u]+sz[u];
}
if(lst<dfn[i]+sz[i])upd(1,1,m,lst,dfn[i]+sz[i]-1,e[i]);
}
for(int i=1;i<=n;i++)par[i]=i,siz[i]=1;
solve(1,1,m,1);
for(int i=1;i<=m;i++)puts(ans[dfn[i]]?"excited":"naive");
return 0;
}

最新文章

  1. Chrome Restful Api 测试工具 Postman-REST-Client离线安装包下载,Axure RP Extension for Chrome离线版下载
  2. Sql用变量拼语句
  3. 数据可视化(4)--jqplot
  4. 根据子查询批量删除的sql语句
  5. js跨域及解决方案
  6. Restrict each user to a single session in window server 2008 R2 or 2012
  7. 怒刷DP之 HDU 1160
  8. PHP中zlib扩展实现GZIP压缩输出各种方法总结
  9. FullCalendar 的学习笔记(二)
  10. PL/SQL“ ORA-14551: 无法在查询中执行 DML 操作”解决
  11. Android EclipseIDE技巧
  12. Winform界面中主从表编辑界面的快速处理
  13. TP手册学习第三天
  14. 多态原理探究-从C++编译器角度理解多态的实现原理
  15. 棋盘的完美覆盖问题,c++代码实现
  16. lucene基础
  17. C#源码发送简单的HTTP请求
  18. /linux-command-line-bash-shortcut-keys/
  19. 【RMAN】RMAN-05001: auxiliary filename conflicts with the target database
  20. 如何在Virtualbox中对Ubuntu系统根分区扩容

热门文章

  1. 【温故知新】—— React/Redux/React-router4基础知识&amp;独立团Demo
  2. 自己动手写android图片异步载入库
  3. 倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
  4. Exposing the Outlook Password Secrets
  5. python 类特殊成员
  6. Linux非阻塞IO(八)使用epoll重新实现非阻塞的回射服务器
  7. Linux——环境变量的文件及配置
  8. java替换文本中所有的正则符号 Java问题通用解决代码
  9. Android适配方案小结(二)
  10. IntelliJ IDEA(2017)下载并破解