BZOJ3069 : [Pa2011]Hard Choice 艰难的选择

在每条边两个点中间加上一个虚拟点代表这条边权,就可以化边权为点权。

把没删掉的边用LCT维护一棵生成树,树边都是桥。

对于一条非树边,把树上对应路径上所有边的权值都修改为0,表示都不是桥。

然后倒着处理询问,对于每次删掉的边,把两点路径上边权都修改为0。

询问等价于查询两点间边权和,若两点连通且路径上不存在桥,则有解。

#include<cstdio>
#include<map>
const int N=200010,BUF=5000000;
char Buf[BUF],*buf=Buf;
int a[N],n,m,i,x,fa[N],edge[N][2],ask[N][4],q;
struct LCT{int f,son[2],sum,data;bool rev,tag;}T[N];
int father(int x){return fa[x]==x?x:fa[x]=father(fa[x]);}
std::map<int,bool>del[N>>1];
inline void swap(int&a,int&b){int c=a;a=b;b=c;}
inline bool isroot(int x){return !T[x].f||T[T[x].f].son[0]!=x&&T[T[x].f].son[1]!=x;}
inline void rev1(int x){if(!x)return;swap(T[x].son[0],T[x].son[1]),T[x].rev^=1;}
inline void makezero1(int x){if(!x)return;T[x].sum=T[x].data=0;T[x].tag=1;}
inline void pb(int x){
  if(T[x].rev)rev1(T[x].son[0]),rev1(T[x].son[1]),T[x].rev=0;
  if(T[x].tag)makezero1(T[x].son[0]),makezero1(T[x].son[1]),T[x].tag=0;
}
inline void up(int x){T[x].sum=T[x].data|T[T[x].son[0]].sum|T[T[x].son[1]].sum;}
inline void rotate(int x){
  int y=T[x].f,w=T[y].son[1]==x;
  T[y].son[w]=T[x].son[w^1];
  if(T[x].son[w^1])T[T[x].son[w^1]].f=y;
  if(T[y].f){
    int z=T[y].f;
    if(T[z].son[0]==y)T[z].son[0]=x;else if(T[z].son[1]==y)T[z].son[1]=x;
  }
  T[x].f=T[y].f;T[x].son[w^1]=y;T[y].f=x;up(y);
}
inline void splay(int x){
  int s=1,i=x,y;a[1]=i;
  while(!isroot(i))a[++s]=i=T[i].f;
  while(s)pb(a[s--]);
  while(!isroot(x)){
    y=T[x].f;
    if(!isroot(y)){if((T[T[y].f].son[0]==y)^(T[y].son[0]==x))rotate(x);else rotate(y);}
    rotate(x);
  }
  up(x);
}
inline void access(int x){for(int y=0;x;y=x,x=T[x].f)splay(x),T[x].son[1]=y,up(x);}
inline void makeroot(int x){access(x);splay(x);rev1(x);}
inline void link(int x,int y){makeroot(x);T[x].f=y;access(x);}
inline void makezero(int x,int y){
  if(father(x)!=father(y)){
    fa[father(x)]=father(y);
    n++;
    T[n].sum=T[n].data=1;
    link(x,n);link(n,y);
    return;
  }
  makeroot(x);
  access(y);
  splay(x);
  makezero1(x);
}
inline int getsum(int x,int y){
  if(father(x)!=father(y))return 1;
  makeroot(x);
  access(y);
  splay(x);
  return T[x].sum;
}
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
int main(){
  fread(Buf,1,BUF,stdin);read(n);read(m);read(q);
  for(i=1;i<=n;i++)fa[i]=i;
  for(i=1;i<=m;i++){
    read(edge[i][0]);read(edge[i][1]);
    if(edge[i][0]>edge[i][1])swap(edge[i][0],edge[i][1]);
  }
  for(i=1;i<=q;i++){
    while(*buf!=‘Z‘&&*buf!=‘P‘)buf++;
    ask[i][0]=x=*buf==‘P‘,buf++;
    read(ask[i][1]);read(ask[i][2]);
    if(ask[i][1]>ask[i][2])swap(ask[i][1],ask[i][2]);
    if(!x)del[ask[i][1]][ask[i][2]]=1;
  }
  for(i=1;i<=m;i++)if(!del[edge[i][0]][edge[i][1]])if(father(edge[i][0])!=father(edge[i][1])){
    fa[father(edge[i][0])]=father(edge[i][1]);
    n++;
    T[n].sum=T[n].data=1;
    link(edge[i][0],n);link(n,edge[i][1]);
    del[edge[i][0]][edge[i][1]]=1;
  }
  for(i=1;i<=m;i++)if(!del[edge[i][0]][edge[i][1]])makezero(edge[i][0],edge[i][1]);
  for(i=q;i;i--)if(!ask[i][0])makezero(ask[i][1],ask[i][2]);else ask[i][3]=getsum(ask[i][1],ask[i][2]);
  for(i=1;i<=q;i++)if(ask[i][0])puts(ask[i][3]?"NIE":"TAK");
  return 0;
}

  

时间: 2024-08-10 23:28:56

BZOJ3069 : [Pa2011]Hard Choice 艰难的选择的相关文章

3069: [Pa2011]Hard Choice 艰难的选择

Description Byteasar是一个很纠结的人.每次他经过Bytetown的时候都知道有至少2条不同的路径可以选择,这导致他必须花很长时间来决定走哪条路.Byteasar最近听说了Bytetown的修路计划,他可能是唯一一个为此感到高兴的人——他有机会消除他的烦恼. 在Byteasar一共有n个岔口,连接着m条双向道路.两条路径完全不同当且仅当他们没有公共的道路(但是允许经过相同的岔口). Byteasar想知道:对于两个岔口x y,是否存在一对完全不同的路径. Input 第一行3个

UVA 1175 Ladies&#39; Choice 女士的选择(稳定婚姻问题,GS算法)

题意: 给出每个男的心目中的女神排序,给出每个女的心目中的男神排序,即两个n*n的矩阵,一旦任意两个非舞伴的男女同学觉得对方都比现任舞伴要好,他们就会抛弃舞伴而在一起.为了杜绝这种现象,求每个男的最后所搭配的女伴是谁. 思路: 怎么感觉题意有点问题,输出的是第i行的男人所搭配的女人,即输出的是女人! 每个男人依次选择最喜欢的女人求婚,若同一个女的没人抢,则临时抢亲成功,若需要抢,明显女的都是喜欢挑长腿oba啦,矮冬瓜自动加入单身狗队列继续求婚!当单身狗所求的女神已订婚,只要女神更爱单身狗,没有什

JZOJ 3913. 艰难的选择

题目 Description Yzx已经当过多次“媒人”了.他因此获得了许多经验.例如,距Yzx观察,身高相近的人似乎比较合得来.Yzx在学校策划了一次大型的“非常男女”配对活动.对于这次活动的参与者,Yzx有自己独特的选择方式.他希望能选择男女人数相等且身高都很接近的一些人.这种选择方式实现起来很简单,他让学校的所有人按照身高排成一排,然后从中选出连续的若干个人,使得这些人中男女人数相等.Yzx当然希望他能选出的人越多越好,请告诉他最多可以选出多少人来. Input 第一行有一个正整数n,代表

选择&mdash;&mdash;ERP信息系统选型

做一次选择并不难,难的是做一次坚定而正确的选择.TCL电脑公司的ERP软件选型就是一次正确而艰难的选择过程.让我们从头说起吧!­ 业界都知道TCL电脑是IT行业的新入行者,更知道TCL的另一个诠释:"Today China Lion".而我们,作为TCL电脑人,在将精彩留给别人时,也不得不开始对我们自己及我们的生存环境进行反省与思考:我们一边要接受前方销售将士频频货源告急的抱怨,一边又要面临PC原材料更新换代造成的库存压力:我们一面要接受IT行业前所未有的变化速度与产品更替,一面是传统

python random 从集合中随机选择元素

使用python random模块的choice方法随机选择某个元素 from random import choice foo = ['a', 'b', 'c', 'd', 'e'] print (choice(foo)) 使用python random模块的sample函数从列表中随机选择一组元素 list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] slice = random.sample(list, 5) #从list中随机获取5个元素,作为一个片断返回 pri

cong

Directions:  Study the following cartoon carefully and write an essay in which you should 1) describe the cartoon, 2) interpret its meaning, and 3) point out its implications in our life. You should write about 160—200 words neatly on ANSWER SH

tcp协议分析

tcp协议解析 TCP在网络OSI的七层模型中的第四层--Transport层,IP在第三层--Network层,ARP在第二层--Data Link层.在第二层上的数据,我们叫Frame,在第三层上的数据叫Packet,第四层的数据叫Segment. 我们程序的数据首先会打到TCP的Segment中,然后TCP的Segment会打到IP的Packet中,然后再打到以太网Ethernet的Frame中,传到对端后,各个层解析自己的协议,然后把数据交给更高层的协议处理 TCP头格式 TCP数据段格

谈谈对CAP定理的理解

谈谈对CAP定理的理解 CAP定理的常规解释是任何分布式系统只能在一致性(Consitency),可用性(Availability)和分区容忍性(Partition Tolerance)中三选二.这个解释很让人费解,笔者在看了一些文章后谈谈我对它的理解,还请斧正. 从问题出发 假设我们用一台服务器A对外提供存储服务,为了避免这台服务器宕机导致服务不可用,我们又在另外一台服务器B上运行了同样的存储服务.每次用户在往服务器A写入数据的时候,A都往服务器B上写一份,然后再返回客户端.一切都运行得很好,

TCP 的那些事儿(上)

http://coolshell.cn/articles/11564.html TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子问题和阴暗面.所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能让人有很多收获.关于TCP这个协议的细节,我还是推荐你去看W.Richard Stevens的<TCP/IP 详解 卷1:协议>(当然,你也可以去读一下RFC793以及后面N多的RFC).另外,本文我会使用英文术语,这样方便你通过这些英文关键词来查找相关的技术文档. 之所以