HDU 5467
第一次写LCT,各种模板加入。。。以后都只遇到有新意的题目再更新了
这道题就是LCT,但是,难在一个回退的操作。这时,可以通过改变执行顺序,先把要回退后再做的操作先执行了,再回退到之前的执行。这时,建立一棵操作树,使用DFS可以回退的特点,就能完成这一功能。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define LL long long
using namespace std; const int MAX=300050;
const LL MOD=1e9+7;
int fa[MAX],ch[MAX][2],son[MAX],nxt[MAX],rev[MAX];
int n,q;
int opt_x[MAX],opt_u[MAX],opt_v[MAX],opt_d[MAX];
LL val[MAX],mul[MAX];
LL ans[MAX];
set<long long>st;
int stack[MAX]; void update(int x){
int l=ch[x][0],r=ch[x][1];
mul[x]=val[x];
if(l) mul[x]=mul[x]*mul[l]%MOD;
if(r) mul[x]=mul[x]*mul[r]%MOD;
} void pushdown(int x){
int l=ch[x][0],r=ch[x][1];
if(rev[x]){
rev[x]^=1;rev[l]^=1;rev[r]^=1;
swap(ch[x][0],ch[x][1]);
}
} bool isroot(int x){
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
} void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if(ch[y][0]==x)l=0;else l=1;r=l^1;
if(!isroot(y))
{
if(ch[z][0]==y)ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
update(y);update(x);
} void splay(int u){
int top=0; stack[++top]=u;
for(int i=u;!isroot(i);i=fa[i]) stack[++top]=fa[i];
while(top) pushdown(stack[top--]);
while(!isroot(u)){
int y=fa[u],z=fa[y];
if(!isroot(y)){
if(ch[y][0]==u^ch[z][0]==y)rotate(u);
else rotate(y);
}
rotate(u);
}
} bool connect(int u,int v){
while(fa[u]) u=fa[u];
while(fa[v]) v=fa[v];
return u==v;
} void access(int u){
for(int t=0;u;t=u,u=fa[u]){
splay(u),ch[u][1]=t,update(u);
}
} void makeroot(int x){
access(x),splay(x),rev[x]^=1;
} bool link(int u,int v){
if(u>v) swap(u,v);
if(u==v) return false;
if(connect(u,v)) return false;
makeroot(u),fa[u]=v;
st.insert(MAX*u+v);
return true;
} bool cut(int u,int v){
if(u>v) swap(u,v);
if(u==v) return false;
if(st.find(MAX*u+v)==st.end()) return false;
makeroot(u),access(v),splay(v);
fa[u]=0,ch[v][0]=0;
st.erase(MAX*u+v);
return true;
} void dfs(int x){
bool done=false;
LL tmp;
int u=opt_u[x],v=opt_v[x];
if(opt_x[x]==1) done=link(u,v);
if(opt_x[x]==2) done=cut(u,v);
if(opt_x[x]==4){
if(u==v) ans[opt_d[x]]=val[u];
else{
if(connect(u,v)){
makeroot(u);
access(v),splay(v);
ans[opt_d[x]]=mul[v];
}
else{
ans[opt_d[x]]=0;
}
}
}
if(opt_x[x]==5){
done=true;
splay(u);
tmp=val[u];
val[u]=v*(v-1)/2%MOD;
update(u);
}
for(int i=son[x];i;i=nxt[i]) dfs(i);
if(done){
if(opt_x[x]==1) done=cut(u,v);
if(opt_x[x]==2) done=link(u,v);
if(opt_x[x]==5){
splay(u);
val[u]=tmp;
update(u);
}
}
} int main(){
int T;
LL k;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
scanf("%lld",&k);
val[i]=mul[i]=k*(k-1)/2%MOD;
}
for(int i=0;i<=n+10;i++) rev[i]=0,fa[i]=0,ch[i][0]=ch[i][1]=0;
for(int i=0;i<=q+10;i++) nxt[i]=son[i]=0;
st.clear();
int tot=0;
for(int i=1;i<=q;i++){
scanf("%d",&opt_x[i]);
if(opt_x[i]==3){
scanf("%d",&opt_u[i]);
nxt[i]=son[opt_u[i]],son[opt_u[i]]=i;
}
else{
scanf("%d%d",&opt_u[i],&opt_v[i]);
nxt[i]=son[i-1],son[i-1]=i;
if(opt_x[i]==4){
opt_d[i]=++tot;
}
}
}
dfs(0);
for(int i=1;i<=tot;i++){
printf("%lld\n",ans[i]);
}
}
return 0;
}
HDU 5467的更多相关文章
- HDU 1284 钱币兑换问题 母函数、DP
题目链接:HDU 1284 钱币兑换问题 钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (J ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 3791二叉搜索树解题(解题报告)
1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...
随机推荐
- group by 和 select
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面.
- HTML--文本输入框、密码输入框
当用户要在表单中键入字母.数字等内容时,就会用到文本输入框.文本框也可以转化为密码输入框. 语法: <form> <input type="text/password&qu ...
- 【洛谷4396/BZOJ3236】[AHOI2013]作业(莫队+分块/树状数组/线段树)
题目: 洛谷4396 BZOJ3236(权限) 这题似乎BZOJ上数据强一些? 分析: 这题真的是--一言难尽 发现题面里没说权值的范围,怕出锅就写了离散化.后来经过面向数据编程(以及膜神犇代码)知道 ...
- drupal 8——图片组(list)在前台的显示顺序在登录状态和非登录状态不同
问题描述:该页面是通过view来输出的,然而,登录状态下其页面中的图片组输出顺序是乱序的,而非登录状态下则根据id值升序输出. 原因:在原view配置页面中,没有配置默认的排序字段 解决方案:在vie ...
- ionic2/3 禁止屏幕旋转,禁止横屏,竖屏
ionic2/ionic3禁止屏幕旋转,及解除禁止旋转 1.添加插件: cmd到项目目录---> cordova plugin add cordova-plugin-screen-orienta ...
- VHDL_ADC之cic_diffcell
library IEEE; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library edclib; use edclib.pkg_ ...
- 拍拍贷投资工具|拍拍贷投标工具|PPD投标工具|PPD投资工具介绍
我们先来分析一下现在市场上在PPD投资的途径: 其他解决方案 1.在网站或者手机客户端手动投标 这种方法对于非常小额的资金是可以的,稍微多一点就会发现不可行,目前PPD手动刷新出来的标几乎都是你刚刷新 ...
- 白盒-CNN纹理深度可视化: 使用MIT Place 场景预训练模型
MIT发文:深度视觉的量化表示................ Places2 是一个场景图像数据集,包含 1千万张 图片,400多个不同类型的场景环境,可用于以场景和环境为应用内容的视觉认知任务. ...
- docloud后台管理项目(前端篇)
以下内容与主题无关,如果不想看可以直接忽视 !--忽视开始--! 给大家推荐一款强大的编辑器,那就是集响应快.体验好.逼格高.功能丰富为一体的sublime text 3.它除了以上特点,还有一个最重 ...
- The Standard SSL Handshake
The following is a standard SSL handshake when RSA key exchange algorithm is used: 1. Client Hello ...