11.24 模拟赛

T1 bzoj 4730 Alice和Bob又在玩游戏

题目大意:

Alice和Bob在玩游戏 n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最小的点

Alice和Bob轮流操作,每回合选择一个没有被删除的节点x,将x及其所有祖先全部删除,不能操作的人输

思路:

根据博弈论的一些定理可以得到一个优秀的$n^2$做法

由$SG$定理得 每个点的$SG$函数值为$mex${子树内一个点的SG xor 该根节点其余儿子的SG}

因此对于每个点我们可以开一个trie树表示这个点的SG集合

合并的时候每个子树的¥trie$树$xor$其余子树的$xor$和 然后像线段树合并一样合并$trie$树即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i)
11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i)
12 #define ren for(register int i=fst[x];i;i=nxt[i])
13 #define Fill(x,t) memset(x,t,sizeof(x))
14 #define ll long long
15 #define inf 2139062143
16 #define MAXN 200100
17 using namespace std;
18 inline int read()
19 {
20     int x=0,f=1;char ch=getchar();
21     while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();}
23     return x*f;
24 }
25 int n,m,fst[MAXN],to[MAXN<<1],nxt[MAXN<<1],cnt,vis[MAXN],sg[MAXN];
26 int ls[MAXN*20],rs[MAXN*20],tag[MAXN*20],tot,ans,sz[MAXN*20],rt[MAXN*20];
27 const int maxDep=16;
28 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
29 void pshd(int k,int Dep)
30 {
31     if((tag[k]>>Dep)&1) swap(ls[k],rs[k]);
32     tag[k]&=((1<<Dep)-1);
33     tag[ls[k]]^=tag[k],tag[rs[k]]^=tag[k],tag[k]=0;
34 }
35 int merge(int x,int y,int Dep)
36 {
37     if(!(x*y)) return x|y;
38     pshd(x,Dep);pshd(y,Dep);
39     ls[x]=merge(ls[x],ls[y],Dep-1),rs[x]=merge(rs[x],rs[y],Dep-1);
40     return x;
41 }
42 void ins(int &x,int val,int Dep)
43 {
44     if(!x) x=++tot,sz[x]=1,ls[x]=rs[x]=tag[x]=0;if(!(~Dep)) return ;
45     pshd(x,Dep);ins((val&(1<<Dep))?rs[x]:ls[x],val,Dep-1);
46     sz[x]=sz[ls[x]]+sz[rs[x]];
47 }
48 int mex(int x,int res=0)
49 {
50     dwn(i,maxDep,0)
51     {
52         if(sz[ls[x]]<(1<<i)) x=ls[x];
53         else res|=(1<<i),x=rs[x];
54     }
55     return res;
56 }
57 void dfs(int x,int fa)
58 {
59     int sum=0;vis[x]=1;
60     ren if(to[i]!=fa) {dfs(to[i],x);sum^=sg[to[i]];}
61     ren if(to[i]!=fa) {tag[rt[to[i]]]^=(sum^sg[to[i]]);rt[x]=merge(rt[x],rt[to[i]],maxDep);}
62     ins(rt[x],sum,maxDep);sg[x]=mex(rt[x]);
63 }
64 int main()
65 {
66     int T=read();
67     while(T--)
68     {
69         n=read(),m=read(),tot=cnt=ans=0;int a,b;
70         while(m--) {a=read(),b=read();add(a,b);add(b,a);}
71         rep(i,1,n) if(!vis[i]) {dfs(i,0);ans^=sg[i];}
72         puts(ans?"Alice":"Bob");
73         rep(i,1,n) fst[i]=vis[i]=sg[i]=rt[i]=0;
74     }
75 }

T2 bzoj 4731 魔法小程序

题目大意:

有这样一段魔法的程序:(其中所有的数组下标从0 开始,所有的除法的结果为整数,且向0取整)

现在给出数组$c$ 求数组$b$

思路:

相当于对每个数拆成一个K维空间的点 每一维长度不一样 数组$a$代表每一维的长度

$c_i$为这个K维空间内第i个点所对应多维立方体内的点权和(相当于前缀和

因为一共只有m个点 所以有意义且长度大于1的点不超过$log \space m$个

因此我们可以暴力把这些维数还原回去

对于每一维 我们从m-1枚举到0 可以减去次一维的立方体的影响

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #define rep(i,s,t) for(register int i=(s);i<=(t);++i)
11 #define dwn(i,s,t) for(register int i=(s);i>=(t);--i)
12 #define ren for(int i=fst[x];i;i=nxt[i])
13 #define Fill(x,t) memset(x,t,sizeof(x))
14 #define ll long long
15 #define inf 2139062143
16 #define MAXN 1001000
17 using namespace std;
18 inline ll read()
19 {
20     ll x=0,f=1;char ch=getchar();
21     while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
22     while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();}
23     return x*f;
24 }
25 ll n,m,a[MAXN],c[MAXN],mul[MAXN];
26 int main()
27 {
28     n=read();printf("%d\n",n);rep(i,0,n-1) {a[i]=read();printf("%lld ",a[i]);if(a[i]==1) n--,i--;}
29     m=read();rep(i,0,m-1) c[i]=read();mul[0]=1,a[n++]=inf;int x,y;
30     rep(i,1,n-1) {mul[i]=mul[i-1]*a[i-1];if(mul[i]>m) {n=i;break;}}
31     rep(i,0,n-1)
32     {
33         x=m%mul[i],y=(m/mul[i])%a[i];
34         dwn(j,m-1,0) {if(x) x--;else x=mul[i]-1,y=y?y-1:a[i]-1;if(y) c[j]-=c[j-mul[i]];}
35     }
36     printf("\n%d\n",m);
37     rep(i,0,m-1) printf("%lld ",c[i]);
38 }

bzoj 4732 数据交互

这道ddp并不可做(因为甚至没学ddp 有机会再回来

原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10022920.html

时间: 2024-11-04 02:46:11

11.24 模拟赛的相关文章

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

2018/5/24模拟赛总结

shzr带病AK虐爆全场... T1n皇后: 这题没啥好说的... T2有重复元素的排列问题: [问题描述] 设R={ r1, r2 , -, rn}是要进行排列的n个元素.其中元素r1, r2 , -, rn可能相同.试设计一个算法,列出R的所有不同排列. [编程任务] 给定n 以及待排列的n 个元素.计算出这n 个元素的所有不同排列. [输入格式] 由perm.in输入数据.文件的第1 行是元素个数n,1≤n≤500.接下来的1 行是待排列的n个元素. [输出格式] 计算出的n个元素的所有不

11.4 模拟赛

终于AK了,虽然第三题主要是搞月想出来的 T1: n个1*1的小方块,把这些小方块拼成一个图形,使这个图形周长最小 思路: 枚举拼成长方形的长为i,宽为n/i 可得面积 (i+n/i+(bool)(n%i))*2 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstr

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

2017/11/3模拟赛

块(block)[问题描述]拼图达人小 C 手里有 n 个 1*1 的正方形方块, 他希望把这些方块拼在一起, 使得拼出的图形周长最小, 要求方块不能重叠. 擅长拼图的小 C 一下就求出了这个周长, 顺便他想考考你会不会求.[输入格式]多组数据, 第一行一个正整数 T, 表示数据组数.接下来 T 行, 每行一个正整数 n, 表示方块数.[输出格式]输出 T 行, 每行一个正整数, 表示答案.[样例输入]3 4 1122[样例输出]81420[数据范围]对于 20%的数据, n<=20:对于 40

2017/11/1模拟赛

磁星(magnet)[题目描述]在 B 城呆惯了的小 H 决定去外太空溜达一圈.人类现已发现并开发的星球(包括小 H 所在的星球)有 n 个,并且在这 n 个星球之中,人们发现了 m 对两个星球的关系.关系"xy"表示的是星球 x 对星球 y 有 1 一个单位的引导力,由于引导力还具有传递性,如果星球 x 对星球 y 能有恰好 a 个单位的引导力,星球y 对星球 z 能有恰好 b 个单位的引导力,那么星球 x 对星球 z 就能有恰好 a+b 个单位的引导力. 换言之,星球 x 对星球

11.2 模拟赛

T1: tarjan裸不能再裸了 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdlib> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 #define inf 2147483611 10 #defi