hdu_5927_Auxiliary Set(xjb搞)

题目链接:hdu_5927_Auxiliary Set

题意:

给一棵n个节点的树,最开始全部都是重点,现在有q个询问,每次给你一些轻点,并叫你输出整棵树的重点数量,

轻点可能会变为重点,如果这个轻点是两个重点的lca。

题解:

这里 我把有重点的子树叫重子树,一个重点都没有的子树叫轻子树。

一个轻点如果有两个重子树,那么这个轻点就会变为重点,可以画图试试。

然后我们就将轻点从树的最底层开始更新

x为这个点的子树个数,n为这个点的轻子树个数,

如果x-n=0,那么这个点的父亲节点的n就++

如果x-n<=1那么这个点就不能变会重点

最后统计一下轻点变回重点的个数

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4
 5 const int N=1e5+7;
 6 int ic=1,t,n,q;
 7 int g[N],v[N*2],nxt[N*2],ed,dfs_idx,hsh[N];
 8
 9 struct node
10 {
11     int in,pre,n,x,col,idx;
12     bool operator < (const node &b)const{return in>b.in;}
13 }nd[N],tmp[N];
14
15 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
16
17 void init()
18 {
19     memset(g,0,sizeof(g));
20     ed=0,dfs_idx=0;
21 }
22
23 void dfs(int u=1,int pre=0)
24 {
25     nd[u].idx=u,nd[u].in=++dfs_idx,nd[u].pre=pre;
26     nd[u].col=1,nd[u].n=0,nd[u].x=0;
27     for(int i=g[u];i;i=nxt[i])if(v[i]!=pre)nd[u].x++,dfs(v[i],u);
28 }
29
30 int main(){
31     scanf("%d",&t);
32     while(t--)
33     {
34         printf("Case #%d:\n",ic++);
35         init();
36         scanf("%d%d",&n,&q);
37         F(i,1,n-1)
38         {
39             int x,y;
40             scanf("%d%d",&x,&y);
41             adg(x,y),adg(y,x);
42         }
43         dfs();
44         F(i,1,q)
45         {
46             int nn,x;
47             int ans=0;
48             scanf("%d",&nn);
49             F(j,1,nn)scanf("%d",&x),tmp[j]=nd[x];
50             sort(tmp+1,tmp+1+nn);
51             F(j,1,nn)hsh[tmp[j].idx]=j;
52             F(j,1,nn)
53             {
54                 if(tmp[j].x-tmp[j].n<2)tmp[j].col=0;
55                 if(tmp[j].x-tmp[j].n==0)tmp[hsh[nd[tmp[j].idx].pre]].n++;
56             }
57             F(j,1,nn)
58             {
59                 if(tmp[j].col==1)ans++;
60                 hsh[tmp[j].idx]=0;
61             }
62             printf("%d\n",ans+n-nn);
63         }
64     }
65     return 0;
66 }

时间: 2024-12-08 14:50:35

hdu_5927_Auxiliary Set(xjb搞)的相关文章

hdu_5805_NanoApe Loves Sequence(xjb搞)

题目链接:hdu_5805_NanoApe Loves Sequence 题意: 给你n个数,现在要删一个数,删每个数的概率是一样的,现在问你删一个值后的相邻数绝对值最大差的期望是多少,因为担心精度误差,让你答案乘n 题解: 先算出不删数的绝对值最大的差ma并记录位置,如果要删的数不是刚才求出来的位置,那么ans+=max(abs(a[i-1]-a[i+1],ma).如果是,那么重新求一下最大值就行了,因为最多重求两次,所以总复杂度还是O(n). 1 #include<cstdio> 2 #i

hdu_5813_Elegant Construction(xjb搞)

题目链接:hdu_5813_Elegant Construction 题意: 给你n个点,每个点要可以到达ai个点,可以直接可以间接,不能有环,问是否可行,如果可行就任选一种方式连接,并输出连接的边数和边 题解: 我们按每个点要能到达的点数从小到大排序,然后枚举每个点i,对前面的j(j<i)连一条边,这样保证能到达ai个点,如果第i个点大于等于i,那么肯定没有方案,此时不能向后面的点连边,如果连了就成环了. 1 #include<bits/stdc++.h> 2 using namesp

[HDU5902]GCD is Funny(xjb搞)

题意:n个数每次选三个数删除,取其中两个数将gcd放回去两次,问最后剩的数可能是多少 分析:考虑最优情况: 先拿出三个数,留下两个x,x  再来一个y,(x,x,y)我们可以删去一个x,留下两个gcd(x,y),这两个gcd(x,y)等价于刚才的两个x,x 也就是每次操作我们都可以有一个额外的数让我们删去,并不断扩充gcd 于是答案就是所有子集的gcd 但第一次我们必定删去一个数,它没法加入gcd操作中,所有n个子集的gcd不能作为最终结果 即答案就是2<=size<n的子集的gcd 可以先跑

BZOJ3669: [Noi2014]魔法森林

传送门 高级数据结构学傻系列 正解似乎是最短路xjb搞,但是用LCT瞎搞搞也是很吼啊. 从贪心开始,按照每条边a的大小随意sort一下. 对于每个边,我们check两点的联通性,如果联通的话取b最大的值,如果大于当前边的b的话就就删除最大边,把这条边加进去. 如果不连通的话直接添加即可. LCT滋次这些操作,所以大力LCT即可. //BZOJ 3669 //by Cydiater //2017.2.16 #include <iostream> #include <queue> #i

acm刷题记录

我感觉毫无目的地刷题没有意义,便记录每周的刷题,以此激励自己! ----------6.6-------- [vijos1055]奶牛浴场                                      最大化               推荐IOI论文<浅谈用极大化思想解决最大子矩形问题> codeforces 679B - Bear and Tower of Cubes      xjb搞 codeforces  680A - Bear and Five Cards       

红书上的几道搜索例题

Holedox Moving poj 1324 题意:贪吃蛇,n*m的网格,蛇长度<=8,给出蛇的每个身体的位置,求到(1,1)点的最短距离 http://www.cnblogs.com/longdouhzt/archive/2011/11/17/2253233.html这个xjb搞,效果还是不错的 分析:状态数一定,目标一定,压缩状态然后bfs,但是每一位都用(x,y)来表示状态太大,那么还要转换状态,蛇头位置显然要表示,那么剩下的身体只要知道上一段身体在哪,就可以知道现在的坐标了,那么,可以

Codeforces Round #367 (Div. 2) D. Vasiliy&#39;s Multiset

题目链接:Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset 题意: 给你一些操作,往一个集合插入和删除一些数,然后?x让你找出与x异或后的最大值 题解: trie树xjb搞就行,每次要贪心,尽量满足高位为1. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 using namespace std; 4 5 namespace trie 6 {

2016年11月15日noip模拟赛

苟.. 1.谜题 1 /* 2 考虑这题,该怎么xjb搞 3 嗯我说出了题解xjb搞.. 4 由题意 易得 N个 二位数字(一位数加个0) 如果是连续的,那么就成立. 5 反过来做. 6 7 方法2:n<4有解,其他无解 8 */ 9 #include <iostream> 10 #include <cmath> 11 #include <stdio.h> 12 #include <string> 13 #include <string.h>

线段树+离线 hdu5654 xiaoxin and his watermelon candy

传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足要求 思路:刚開始看错题目了,原来三元组是连续3个,这作为bc最后一题也太水了把. . . 先一遍预处理.把连续3个满足条件的找出来,放到还有一个数组里排序去重,用这个数组来给三元组哈希.再扫一遍给三元组在之前那个排序好的数组里二分一下得到下标,大概就是哈希一下,用一个数字来表示. 之后的查询.事实上就是.在