摘要:只计算半径小的能看到的半径大的,因为如果计算半径大的看到半径小的,虽然q在其范围内,但是小的不一定能看到大的 那么我们将机器人按照半径降序排序 遍历一次,去查询在[x-r,x+r]范围的,智商在[q-k,q+k]范围内的机器人个数 可以抽象成矩形[x-r,x+r][q-k,q+k]在二维平面上包含的
阅读全文
摘要:题目设计的很好,感觉做了这题对dp的状态有了更深的理解
阅读全文
摘要:#include const int N = 20, MO = 1000003; int a[N][N], n = 10; inline int qpow(int a, int b) { int ans = 1; while(b) { if(b & 1) { ans = 1ll * ans * a % MO; } ...
阅读全文
摘要:比较裸的依赖背包,但是想状态还是想了好久 转移时由于边界问题,虽然可以倒序转移,但当容量为0|1的时候,由于有初始值的存在 很难再原dp数组上进行修改,所以额外用tmp数组来保存修改后的值
阅读全文
摘要:zoj的测评姬好能卡时间。。 求回文子串的个数:只要把p[i]/2就行了: 如果s_new[i]是‘#’,算的是没有中心的偶回文串 反之是奇回文串
阅读全文
摘要:#include using namespace std; #define maxn 500005 int p[maxn]; char s[maxn],s_new[maxn],ch[2]; int start; int init(){ int len=strlen(s); int j=2; s_new[0]='$',s_new[1]='#'; for(int i=...
阅读全文
摘要:#include using namespace std; #define maxn 500005 int n,p[maxn],s[maxn],s_new[maxn]; int init(){ s_new[0]=-2,s_new[1]=-1; int j=2; for(int i=0;imx) mx=i+p[i],id=i; res...
阅读全文
摘要:https://segmentfault.com/a/1190000008484167?tdsourcetag=s_pctim_aiomsg 讲的超好! poj3974 #include<iostream> #include<cstring> #include<cstdio> using names
阅读全文
摘要:卡常卡的我难受 非递归并查集好像写起来常数小一点 下面是完整代码 #include<bits/stdc++.h> using namespace std; #define maxn 1000005 vector<int> G[maxn]; int n,m; int F[maxn]; int Find
阅读全文
摘要:学了差不多一星期的主席树+树链剖分,再来看这题发现其实是个板子题 一开始想复杂了,以为要用类似求树上第k大的树上差分思想来解决这道题,但其实树链上<=k的元素个数其实直接可以用树链剖分来求 具体是把每条树链放到主席树上询问一下求和就好了
阅读全文
摘要:#include<bits/stdc++.h> using namespace std; #define maxn 2005 #define ll long long #define mod 1000000007 ll n,dp[maxn][maxn]; int dfs(int i,int j){
阅读全文
摘要:一些实现上的细节 按照静态主席树建立 T[1-n] 用相同结构的树状数组 S[1-n]来维护 T[1-n] S[i]表示一棵权值线段树的根节点 update:修改位置i,必然要修改S[i],那么S[i+lowbit i]也要修改 query [l,r]:转化成前缀和问题,静态的初始主席树 T[r]-
阅读全文
摘要:#include using namespace std; int n; int main(){ while(cin>>n){ int ans=1; while(n){ if(n&1)ans*=2; n>>=1; } cout<<ans<<endl; } }
阅读全文
摘要:和线段树类似,每个结点也要打lazy标记 但是lazy标记和线段树不一样 具体区别在于可持久化后lazy-tag不用往下传递,而是固定在这个区间并不断累加,变成了这个区间固有的性质(有点像分块的标记了) update就按照这么来 查询时由于lazytag固定在区间上。所以向下查询的时候要把上层的la
阅读全文
摘要:首先要求第k大就想到用主席树来处理 但是不能直接用树链剖分的dfs序来维护,因为一条链对应的dfs下标可能是断开的几段,无法用权值线段树来维护 那么久维护每个点到根节点的全值线段树,结点u的权值线段树记录了其到根节点路径上数值的出现次数 主席树相当于维护了一个前缀和,由树上前缀和可以分析出u->v路
阅读全文
摘要:第一次碰到这种题,不知所措,题解链接 =》 https://www.cnblogs.com/fu3638/p/7426074.html
阅读全文
摘要:线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了。。 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 向上爬时更新操作不用变,但是询问操作需要改变 同样有一些值得注意的地方:向上爬的两条链是有顺序的,合并时顺序不能搞反,也
阅读全文
摘要:边权操作起来也和点权一样,只要把边的权值映射到点上即可,要注意的地方是向上爬的过程中和点权不太一样,还有个特判(WA了几次。。) 完整代码 #include<cstring> #include<cstdio> #include<iostream> using namespace std; #defi
阅读全文
摘要:#include using namespace std; #define ll long long #define maxn 50005 struct Edge{int to,nxt;}edge[maxnsize[son[x]])son[x]=y; } } int top[maxn],id[maxn],rk[maxn],cnt; void dfs2(int x,int tp){ ...
阅读全文
摘要:一篇很好的博客 https://www.cnblogs.com/ivanovcraft/p/9019090.html 树链剖分:将树分割成一条条链,然后按照dfs序进行维护 为什么要进行树链剖分? 首先来说一般的dfs序:可以想象普通的dfs序只能保证同一子树的结点序号是连续的 但是这样的dfs并没
阅读全文
摘要:和向左密集比起来向右密集只需要进行小小的额修改,就是更新的时候从右往左更新。。 自己写的被卡死时间。不知道怎么回事,和网上博客的没啥区别。。 下面的是ac的。。 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstrin
阅读全文
摘要:主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数) 事实上:每个版本的主席树维护了每个值最后出现的位置 这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的
阅读全文
摘要:这种题为什么要用到主席树啊、、8说了,直接上代码
阅读全文
摘要:poj2104找了个板子。。,但是各种IO还可以进行优化 /* 找区间[l,r]第k大的数 */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #defin
阅读全文
摘要:#include #define rep(i,a,b) for(int i=a;i>n>>m){ cin>>p; int x1,y1,x2,y2; rep(i,1,n*m)a[i]=0; while(p--){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ad...
阅读全文
摘要:学了下莫比乌斯反演,实质上mu函数是从容斥原理推出来的 详细的原理解读+例子讲解可以看博客 https://www.cnblogs.com/chenyang920/p/4811995.html 好博客 https://blog.csdn.net/tomandjake_/article/details
阅读全文
摘要:按照nlogn求lis的方法,把lis的状态压缩了,每次新加一个数就把它右边第一个数的位置置为0,然后把这个数加进去 一个需要注意的地方,如果前面都是0,那么状态s中代表0的位置不可以是1,因为这种情况下0不可以被算作是lis里的一位
阅读全文
摘要:枚举fix所在的位置loc即可,然后数位dp即可 这题要注意一种特殊情况,就是所有位都是0的时候对于每个fix都是成立的
阅读全文
摘要:/* 漂亮数定义:可以整除任意数位上的数 求出区间[l,r]之间的漂亮数个数 因为 dp[i][j][k]:i位前模lcm的值是j,i位前lcm是k的漂亮数个数 */ #include using namespace std; #define ll long long ll dp[25][2600][60],has[2600],a[25],len,tot; void init(){/...
阅读全文
摘要:直接用埃氏筛也可以做,但是这题写起来有点恶臭。。 更加简单的写法是直接枚举gcd=k,然后里面再枚举一次i*k,即找到k两个最小的倍数,看起来复杂度很高,但其实也是埃氏筛的复杂度 因为每次枚举gcd,相当于筛法中的枚举筛数,不同的是这题对于每个i在筛的过程中,不会筛到低,而是会中途退出循环,那么当其
阅读全文
摘要:G 容斥原理推公式或者打表oeis 公式推导:fn表示n个元素的排列方案 现在加入了元素n+1,即求fn+1的排列方案 设fn的一种合法排列是 1,,p2,p3,p4...pn,那么将n+1插到n-1个空隙中,其中有个空隙是不能插的,所以有n-2种插法 由于新加入了n+1,所以n个元素某些不合法的排
阅读全文
摘要:A 队友过得没看 B 队友过得没看 F 预处理前缀和+lower_bound时间空间可能都有点卡 处理下公式就能发现规律,因为向下取整不能用前缀和做,但是除数其实就30个,所以直接用sum[i][j]求出[1,i]除以j的前缀和 然后用upper_bound来求即可,注意一些细节的优化,否则会t #
阅读全文
摘要:cf里好像经常出 这些题,一般贪心是搞不了的。。 918C 问有多少子段[l,r]满足合法括号 先从左往右扫,如果问号+‘(' 数量 >= ')' 说明这段区间的 ) 是满足条件的 然后再从右往左扫,如果问号+’)‘数量 >= '(' 说明这段区间的 ’(‘是满足条件的 这就是一个区间合法的充要条件
阅读全文
摘要:一千八的题也不会做了呜呜呜 size[u]表示结点u下的叶子结点, 思维:可以想到一个子树对其父亲会有一个消耗值 考虑一个点如果是max,那么其最大值可以是size[u]-p,p是消耗值最小的子树 一个点如果是min,那么其最大值是size[u]-所有子树的消耗值之和 那么dp[u]表示结点u的最大
阅读全文
摘要:从未见过的船新版本数位dp,,省去了预处理过程,直接进行计算
阅读全文
摘要:cf933A dp题 一开始看错是连续子序列了,然后样例刚好能过。。 然后正解没想出来,网上看了题解:感觉正解是枚举2开始的位置,然后再枚举翻转的区间,pos左右两侧分别求出贡献最大的那个区间,左右两部分的贡献是独立计算的 #include <cstdio> #include <cmath> #in
阅读全文
摘要:/* dp[i][0|1|2]:没有49的个数|最高位是9,没有49的个数|有49的个数 dp[i][0]=10*dp[i-1][0]-dp[i-1][1] dp[i][1]=dp[i-1][0] dp[i][2]=10*dp[i-1][2]+dp[i-1][1] */ #include using namespace std; #define ll long long ll dp[30]...
阅读全文
摘要:cf401D 状态压缩dp好题,每次把新加入集合的数字放在最后即可 /* 它可以通过重新排列数字n, 它没有任何前导零, x除以m后的余数等于0. 每次把新加的数放在最后 dp[i][j]表示状态i下模m=j的数量 dp[i|(1<<k)][j*10+a[k]]+=dp[i][j]; */ #inc
阅读全文
摘要:#include using namespace std; int dp[11][10],n,m; void init(){//dp[i][j]:i位的数,最高位是j dp[0][0]=1; for(int i=1;i=1;i--){//从高到低枚举每位 for(int j=0;j>n>>m,m)cout<<solve(m+1)-solve(n)<<endl;...
阅读全文
摘要:发现cf以前的好题真的很多。。 cf 730j 01背包变形 感觉很好的题 /* 先处理出最少需要t个瓶子 dp[i][j][k]前i个取k个,容量为j时的水的体积 滚动数组搞一下 本题的状态转移必须从合法的状态转移来,所以一定要初始化dp=-INF,并且要有起点dp[i][0][0]=0 其他就是
阅读全文
摘要:#include using namespace std; #define ll long long ll n,k,M,D,anss; ll calc(ll x){ ll tmp=(n/x-1)/k+1; return tmp; } int main(){ cin>>n>>k>>M>>D; for(ll i=1;i>1; ll t=calc...
阅读全文
摘要:如果在两个区域里连点,两个区域内选的点数一定要相等 即a中选出i个点,必须与b中选出i个点相连 连接种类数为 然后我们再来看,如果ab中有两点相连,其中一点再与c相连会出事吗? 很显然不会对答案产生任何影响 所以我们可以得出另外一个结论 a-b b-c c-a所连的边无论如何都是两两独立的 也就是说
阅读全文
摘要:有点自闭的。。为什么我最后的答案是倒着来的啊。。 搞明白了:因为一开始构造的系数就是反着的,,所以主元也倒过来了。。
阅读全文
摘要:#include using namespace std; typedef long long LL; const int maxn=1e5+5; const int MOD=998244353; LL a[maxn],b[maxn]; LL quick_pow(LL a,LL b) { LL ans=1; while(b) { if(b&1)ans=an...
阅读全文
摘要:#include using namespace std; typedef long long LL; const int maxn=1e5+5; const int MOD=998244353; LL a[maxn],b[maxn]; LL quick_pow(LL a,LL b) { LL ans=1; while(b) { if(b&1)ans=an...
阅读全文
摘要:cf711D 成环的和不成环的要单独计算,环用双联通做的QAQ /* 所有情况-成环的情况 */ #include<bits/stdc++.h> using namespace std; #define maxn 200005 #define mod 1000000007 #define ll lo
阅读全文
摘要:cf946D 背包+区间dp 好题 /* 先预处理出每行消去i个1后可以的到的最小时间: 先求每行的前缀和,枚举左端点和右端点,消去的1 cost=tot-sum[r]+sum[l-1],区间长度=r-l+1 time[cost]=min(time[cost],len) 然后再进行行间处理: 就是n
阅读全文
摘要:母函数的定义 母函数计数法则 为什么要(1+x^k),因为有可能不选质量为k的砝码,不选的情况就是x^0=1 整数拆分!
阅读全文
摘要:https://blog.csdn.net/wookaikaiko/article/details/81105031
阅读全文
摘要:这算哪门子dp.. 具体做法就是贪心,建立两个vector存递增序列递减序列,操作过程中a可以合法地匀一个给b 就是判断第i个数放在递增序列里还是放在递减序列里,需要根据后面的数来进行决策
阅读全文
摘要:/* 先一轮求和,再一轮做除法 */ #include using namespace std; char s1[100005],s2[100005]; int a[100005],n; int main(){ cin>>n>>s1>>s2; int tag=0; for(int i=n-1;i>=0;i--){ int b=s1[i]-'a',c=s...
阅读全文
摘要:一开始感觉用莫队可以搞一下,但是看了题解才发现这题其实是倍增套路题 把排列转换成nxt数组,然后倍增dp[i][j]表示第i个数后面有(1<<j)个数的最靠左的区间 然后从右往左扫一次即可
阅读全文