从整张图入手,有两种方法可以得出这道题的结论。 高斯消元:把矩阵列出来,不难发现矩阵的秩为 $n-1$,那么方案数即为 $2^{m-n+1}$。 构造法:我们考虑一棵树。根据经典的剥叶子型构造手法,我们可以得出一棵树的时候方案数唯一,除非要求 $1$ 的点数为奇数,那样状态异或和为 $1$,而我们的操作状态异或和始终为 $0$,所以构造不出来。反之我们随便抽出来一棵生成树,对于其它边,显然取或不取只会反转两个点的状态,而我们的构造法永远可以构造出唯一解,所以方案数就是 $2^{m-n+1}$。 然后我们考虑这个原问题。图上就那么几个知识点,这题又和割点强相关,那就考虑广义圆方树。 假设一开始有 $\rm cnt$ 个连通块,$i$ 有 $\mathrm{deg}_i$ 条连边,和 $\mathrm{cut}_i$ 个方点相连,并且 $i$ 断开后没有一个连通块内有奇点,那么方案数就是 $2^{m-n-\mathrm{deg}_i+\mathrm{cnt}+1+\mathrm{cut}_i}$。时间复杂度 $\mathcal O(Tn)$。甚至不用显式地建出来圆方树,因为我们只需要 $\rm sz$ 和 $\rm cut$ 两个数组,直接求割点就行。
题目2936 [HAOI 2018]反色游戏
AAAAAAAAAA
5
评论
2023-07-22 16:19:47
|
|
算法:字符串哈希 方法通过将字符串的每一位字符转化为一个P进制数(P一般取较大的素数,如131,1007等)取模或用$unsigned long long$自然溢出,再利用前缀和求区间和进行匹配
参考代码:
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ULL; int res; string s; int const P=131; //这里使用131进制数 ULL p[1000010],f[1000010]; //转化进制是用的数组和前缀和数组 int main(){ f[0]=0,p[0]=1; cin>>s; s=" "+s; for (int i=1;i<=s.length();i++){ f[i]=f[i-1]*P+(s[i]-'a'+1); //将s转化为数 p[i]=p[i-1]*P; //和转化进制的方式相似 } int n; ULL res1,res2; scanf("%d",&n); int l1,l2,r1,r2; for (int i=1;i<=n;i++){ scanf("%d %d %d %d",&l1,&r1,&l2,&r2); res1=f[r1]-f[l1-1]*p[r1-l1+1]; res2=f[r2]-f[l2-1]*p[r2-l2+1]; if (res1==res2) printf("Yes\n"); else printf("No\n"); } return 0; }
题目3151 兔子与兔子
6
评论
2023-07-21 17:05:59
|
|
这是一个 $k + 1$ 维偏序问题,如果使用 CDQ 分治的话将收获 $\mathcal O(n\log^k n)$ 的复杂度,而 $n = 40000$ 的情况下 $\log^k n$ 在这题已经是 $10^6$ 的量级,甚至跑不过暴力 $\mathcal O(n^2k)$。 考虑 bitset,我们用 $S_i$ 的一个 bitset 存储当前所有维度均小于 $i$ 的节点,每次对新的维度排序,然后 bitset and 一下即可。不难发现这样可以正确维护。 时间复杂度 $\mathcal O(\frac{n^2k}{\omega})$,其中 $\omega$ 是计算机位数,一般取 $\omega = 32\ \mathrm{or}\ 64$,跑得飞快,比一些实现的不好的 KDTree 正解还要快。
题目2639 [HZOI 2015] 偏序++
AAAAAAAAAA
6
评论
2023-07-16 10:41:47
|
|
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int Hen_hen_eaaaaa(233333);struct Eat{ int Now,Nxt,Bef,Col;}eat[Hen_hen_eaaaaa],frt[Hen_hen_eaaaaa];int n,cnt,STT;bool NOW;inline int R(){ int x=0,f=1;char c='c'; while(c>'9'||c<'0'){f=f*(c=='-'?-1:1);c=getchar();} while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();} return x*f;}int main(){ freopen("csp2021pj_fruit.in","r",stdin); freopen("csp2021pj_fruit.out","w",stdout); n=R(); if(!n) return 0; for(int i=1;i<=n;++i){frt[i].Col=R();frt[i].Bef=i-1;frt[i-1].Nxt=i;} NOW=!frt[1].Col;frt[0].Nxt=1; for(int i=1;i<=n;++i){ if(frt[i].Col!=NOW){ NOW=frt[i].Col; eat[++cnt].Now=i; eat[cnt].Bef=cnt-1; eat[cnt-1].Nxt=cnt; } } int N,NN,NNN; while(frt[0].Nxt&&eat[0].Nxt){ N=eat[0].Nxt; while(N){ printf("%d ",eat[N].Now); NN=eat[N].Now; frt[frt[NN].Bef].Nxt=frt[NN].Nxt; frt[frt[NN].Nxt].Bef=frt[NN].Bef; eat[N].Now=frt[NN].Nxt; NNN=eat[N].Now; if(((frt[NNN].Col!=frt[NN].Col)||(!NNN))&&((frt[eat[eat[N].Bef].Now].Col!=frt[NN].Col)||(!eat[N].Bef))){ eat[eat[N].Bef].Nxt=(eat[N].Bef?((eat[eat[N].Nxt].Nxt&&eat[N].Nxt)?eat[eat[N].Nxt].Nxt:0):eat[N].Nxt); eat[eat[eat[N].Nxt].Nxt].Bef=((eat[N].Bef&&eat[eat[N].Nxt].Nxt&&eat[N].Nxt)?eat[N].Bef:eat[eat[eat[N].Nxt].Nxt].Bef); eat[eat[N].Nxt].Bef=((eat[N].Bef||!eat[N].Nxt)?eat[eat[N].Nxt].Bef:0); } N=eat[N].Nxt; } printf("\n"); } return 0;}
题目3618 [CSP 2021J]小熊的果篮
2
评论
2023-07-12 17:43:24
|
|
nfls 集训的作业题。 考虑 dp。设 $f_i$ 表示前 $i$ 个串的最小代价,$s_i$ 为前缀和,则: $$f_i=\min_{j\in [0,i)} f_j+|s_i-s_j+i-j-L-1|^p$$ 然后发现右边的东西关于 $s_i+i-L-1$ 是一个对称的东西,而且二阶导恒非负。这个时候考虑使用二分队列优化决策单调性。 考虑用三元组 $\left\langle j, l, r \right\rangle$ 表示 $l\to r$ 内的最优决策点为 $j$。 遍历 $i:1\to n$,当队首的 $r\lt i$ 的时候先扔掉,然后令 $l=i$。 对于队尾的一些 $\left\langle j,l,r \right\rangle$,如果 $i\to l$ 的决策比 $j\to l$ 的决策更优,根据决策单调性,$[l,r]$ 内的决策都是 $i$ 更优,直接舍弃 $j$,更替为 $i$。 如果我们弹出的过程中遇到了第一个不满足上述条件的 $\left\langle j,l,r \right\rangle$,那么一定存在一个决策点 $p\in [l,r]$,满足 $\forall x\in [l,p]$,$j$ 更优,$\forall x\in [p+1,r]$,$i$ 更优。直接二分出来就行。 时间复杂度均摊 $\mathcal O(n\log n)$。
题目1372 [NOI 2009]诗人小G
4
评论
2023-07-06 09:41:37
|
|
COGS 为啥不支持 LaTeX 的 \binom,只能用 $\mathrm C$ 表示组合数了。 非常暴力的组合数计数。 考虑拆贡献,对 $i$ 节点,我们枚举 $k = sz_i$,计算 $i$ 子树大小为 $k$ 的方案数,然后直接暴力乘起来。 $i$ 子树内的方案数是 $$(k - 1)!\times \mathrm C_{n - i}^{k - 1}$$ 表示 $\gt i$ 的树中选 $k - 1$ 个进行排列,然后 $i$ 子树外的方案数是 $i!\times (i + 1 - 2)\times (i + 2 - 2)\dots \times (n - k + 1 - 2) = i\times (i - 1)\times (n - k - 1)!$。 那么 $i$ 的方案数就是 $$\sum_{k=1}^{n-i+1} k\times (n - k)\times (k - 1)!\times \mathrm C_{n - i}^{k - 1}\times i\times (i-1) \times (n - k - 1)!$$ 谔谔,为什么会RE,我干啥了,别的地方都能AC啊。
题目2938 [HAOI 2018]苹果树
4
评论
2023-06-22 08:58:56
|