![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
思维
AKone123456
这个作者很懒,什么都没留下…
展开
-
计算几何-----------思维(差分)
解析:求区间[L,R]满足条件的个数?直接前缀和[0,R]-[0,L-1]设区间[0,x],二进制下1的个数为奇数的总和为⌊x2⌋\lfloor\frac{x}{2}\rfloor⌊2x⌋+count(x)count(x):表示x的二进制1的个数是否为奇数按分类讨论x是偶数 答案⌊x2⌋\lfloor\frac{x}{2}\rfloor⌊2x⌋+count(x)x是奇数 答案⌊x+12⌋\lfloor\frac{x+1}{2}\rfloor⌊2x+1⌋#include<bit..原创 2021-05-26 11:17:22 · 303 阅读 · 0 评论 -
追求女神------------思维(奇偶性)
解析:t秒内,从(0,0)走到(x,y) 说明t和(x+y)的奇偶性必须保持一致性且t>=(x+y)#include<bits/stdc++.h>using namespace std;const int N=1e6+10;int t,n;int dx[4]={1,0,-1,0};int dy[4]={0,1,0,-1};struct node{ int k,x,y;}a[N];bool check(int time ,int x,int y,int las..原创 2021-05-26 11:05:39 · 274 阅读 · 0 评论 -
树状数组维护LIS--------------------思维(树状数组)
注意: 必要时需要离散化#include<bits/stdc++.h>using namespace std;const int N=1e5+10000;int c[N];int n,a[N];int f[N];int lowbit(int x){ return x&(-x);}void add(int i,int val){ while(i<N) { c[i]=max(c[i],val); i+=lowbit(i); }}int su原创 2020-12-08 20:25:30 · 402 阅读 · 0 评论 -
B. Johnny and Grandmaster----------------------思维(贪心)
题意:给定n个数和p,现在你需要将n个数分成两个集合A,B 使得两个集合差值绝对值最小解析:一贯的套路我们把pk[i] 当成p进制下,第k[i]位为1.那么就出现了一个性质 25 > 20 + 21 + 22 + 23 +24所以我们按照k[i] 从大到小排第一步找到最大的k[i] ,ans+=pk[i] 相当于把k[i] 放到A集合中第二步 ans-=pk[i] 相当于把k[i]放到B集合中, 直到ans=0 再回到第一步去即可最后还有一个问题,就是an..原创 2020-11-17 16:49:04 · 282 阅读 · 1 评论 -
D. Johnny and Contribution---------------------------思维(贪心)
题意:给定n个点,m条边。每个点都有一个权值ai。问你如何遍历图,使得当前节点为u,与u相连的节点集合{v1,v2,v3,v4,v5…}求出mex{v1,v2,v3,v4…v5} 为 x 判断 a[u]是否等于x 。如果存在序列输出,如果不存在输出-1解析:肯定是贪心的从小到大遍历。所以我们只要把ai排好序。当轮到i节点时,判断与i节点相邻的数的mex是否等于a[i] 如果不等于直接输出-1 即可 。剩下的模拟即可#include<bits/stdc++.h>us..原创 2020-11-17 15:36:39 · 251 阅读 · 0 评论 -
B. Catching Cheaters-----------------------思维(dp)
题意:给定a,b两个串,求最大的S(c,d) = 4 * lcs(c,d) -|c| - |d| 。c和d为a,b串的子串。lcs(c,d) 为c,d的最长公共子序列。解析:设f[i][j]:表示a串以i结尾 和b以j结尾的最长公共子序列长度。当a[i]==b[j]转移方程:f[i][j]=max(f[i][j],f[i-1][j-1]+2)因为a[i]==b[j] 那么前一个状态就是f[i-1][j-1] 。 |c|和|d|的长度都-1了 lcs(c,d)也-1了那么 4x -..原创 2020-11-16 19:59:50 · 310 阅读 · 0 评论 -
A. Knapsack------------------------------------思维(贪心)
题意:给定n个数和w,每个数都有一个权值ai. 问你如何选择使得权值之和在[(w+1)/2,w] 之间。如果满足输出选择数的下标。如果不行输出-1解析:贪心,从大到小贪。例:n=6 w=121 1 1 1 1 11如果从小到大贪,这个样例会输出-1.必须从大到小贪#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=1e6+1000;ll w;struct node..原创 2020-11-16 19:44:17 · 430 阅读 · 2 评论 -
B. Identify the Operations-----------------------思维(组合数学)
题意:给定长度为n的数组A和长度为k的数组B现在需要从A中取出k个数 要和B数组一样。取数规则1.选择ti Ati-1或Ati+1可以加入到B数组2.把选择的ti 踢出去 Ati+1~Atn 各左移一位3.重复1直到选出k个数问?问有多少种不同的取法使得取出k个数和数组B完全一致解析:一眼看上去就是组合数,突破口就是从B数组中的每一位进行讨论因为bi 只可能来自 Ati-1 ,Ati+1 这2种可能分情况第一种情况 :假设bi在A数组的下标为x ,如果A[x-..原创 2020-11-11 16:09:45 · 229 阅读 · 0 评论 -
C. The Delivery Dilemma---------------------思维(贪心排序)
解析:因为A数组是快递并发执行的,所以只需取最大值B数组是需要自己去的时间之和那么我们排序A数组讨论每个位置i,那么A数组[1,i]快递的时间为Ai那么[i+1,n]为我们自己去取的时间,维护一个前缀和即可然后从两个操作取得最大值,然后整体最小即可#include<bits/stdc++.h>using namespace std;const int N=2e5+1000;typedef long long ll;ll b[N]; int t,n;struct n..原创 2020-11-05 23:18:16 · 316 阅读 · 0 评论 -
B. Saving the City---------------------------思维(贪心+模拟+套路)
题意:给定01串,1代表需要爆破的点。爆破1当前位置连通块需要花费a的代价如果把0变成1 需要花费b的代价问最少需要花费多少使得全部变成0题解贪心(套路题):如果在全都不是0的情况下,最少爆破一次。那我们就枚举每两个连通块之间0的个数 然后贪心计算是把0转换成1爆破划算,还是按照连通块个数爆破划算 。假设 区间0的个数为x那么总的修改次数贡献为 :x * b再加上还要爆破一次:x * b+a所以判断一下 x * b+a < 2 * a 如果小于我们就贪心的把这段0都变为..原创 2020-11-05 21:14:01 · 271 阅读 · 0 评论 -
Easy Equation-------------------------思维(差分+前缀和)
解析:由于N非常大,只能O(N)做法所以我们利用前缀和来求出 a+b+c例如求a+b我们只要a即可只要让[i,i+b ]区间+1 代表这个区间里面的数都可以由a,b构造而出所以利用差分 f[i]++,f[i+b+1]–;最后求一遍前缀和即可#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespace std;type...原创 2020-11-01 21:50:52 · 364 阅读 · 0 评论 -
Intelligent Warehouse----------------------思维(dp+素数筛)
题意:给定n个数,选除最多的数,使得任何两个数都是倍数关系解析:设f[i]表示当前选的所有数都是i的约数得最大值假设当前f[4]=2 表示当前有2个数是4的约数那么f[4x]=max(f[4x],f[4]) (2<=x<=N/4) 4*x的约数也一定是2个但是x不能这样枚举 肯定TLE想一想任何一个合数都能由若干个素数乘积得到所以我们只需要乘素数倍即可总的时间复杂度(3e7+nloglogn)解析:#include<cstdio>#include&..原创 2020-10-31 21:16:06 · 161 阅读 · 0 评论 -
D. Destiny--------------------------思维(主席树+贪心剪枝)
题意:查询[l,r]区间中出现的次数大于(r-l+1)/2 的最小数解析:主席树板子题对于查询的时候需要贪心剪枝因为我们求的是最小值一开始肯定先遍历左子树,如果左子树不满足再到右子树上#include<bits/stdc++.h>using namespace std;const int N=3e5+10;int n,q;struct node{ int l,r,cnt;}tr[N*40];int a[N],b[N],root[N*20],idx,num,l,r..原创 2020-10-30 17:25:04 · 239 阅读 · 0 评论 -
Greedy Sequence---------------------------------思维(主席树+贪心)
解析:假设当前位置为x 距离不超过k那么我们可以在[x-k,x] 和 [x,x+k] 去找小于a[x]且最大的数那么可以利用主席树去解决因为要找最大的,所以我们贪心地先遍历到右子树,否则再去左子树#pragma GCC optimize(3 , "Ofast" , "inline")#pragma GCC optimize("Ofast")#pragma GCC target("avx,avx2,fma")#pragma GCC optimization("unroll-loops"...原创 2020-10-26 15:45:47 · 215 阅读 · 0 评论 -
F - A Simple Game HDU - 1851----------------------思维(尼姆博弈+巴什博弈)
题意:n堆物品,每堆至少取一个,最多取k个,谁先取完谁就获胜。解析:巴什博弈:对于每堆物品,至少取一个,最多取k个,根据定义 n%(k+1)尼姆博弈:根据巴什博弈公式 n%(k+1)的余数r (1<=r<=k) 那么就是说剩下来的至少取一个,或者不限取所以先根据巴什博弈求出余数,然后把所有余数异或起来,如果异或=0 说明是奇异局势,先手必败#include<bits/stdc++.h>using namespace std;int t;int n,x,y..原创 2020-10-08 20:00:52 · 181 阅读 · 0 评论 -
E - 邂逅明下 HDU - 2897-----------------------思维(巴什博弈变形)
解析:巴什博弈变形巴什博弈模板结论 : n%(m+1)==0 先手必败,后手必胜证明: 1) n==m+1 先手随意取k个,那么后手一定能取到m+1-k 所以后手先取完2) n=(m+1)*r+s 2-1) s=0 就是(1)的结论2-2) s!=0 先手想要取胜的决策 先手取s个,剩余 (m+1)*r个后手取k个,剩余 (m+1)*r-k个先手取m+1-k个 ,剩余 (m+1)*r-k-m-1+k = (m+1)*(r-1)个那么后手面对的局面就是 n%(m..原创 2020-10-08 18:38:47 · 147 阅读 · 0 评论 -
问题 A: Fermat‘s Optimization Problem--------------------思维(Java大数+二分)
import java.io.*; import java.math.*; import java.util.*; import java.text.*; public class Main { public static void main(String[] args) { Scanner cin = new Scanner (new BufferedInputStream(System.in)); BigIntege.原创 2020-10-05 20:42:48 · 116 阅读 · 0 评论 -
Pie POJ - 3122--------------------思维(浮点数二分)
题意:有n块圆形馅饼,每块的馅饼的半径为r,可以任意切分,剩下的都扔掉。问分给n+1个人,使得每个人获得馅饼的体积最大解析:先让每个数变成r*r,然后二分答案xO(n)计算当前答案为x,可以分得多少块 a[i]/x(1<=i<=n) 假设可以获得cnt块如果cnt>=n+1 说明x过小,使得cnt变大了,所以我们要调整下界#include<iostream>#include<cstdio>#include<cstring>...原创 2020-09-30 15:54:18 · 110 阅读 · 0 评论 -
River Hopscotch POJ - 3258---------------------------思维(二分最小值最大)
题意:有一条宽度为 L 的河,河的两端各有一块石头,河中有 n 块石头,每块石头到河起点一端的石头都有唯一的距离,现在要移除 m 块石头,求移除 m 块石头后,剩下的石头的间距的最小值最大。解析:二分答案间距为x如果两个石头之间的距离<x 那么我们就移除,cnt+=1如果cnt>m 说明x过大,移除了很多石头,我们就需要调整上界使x变小对于最小值最大化:对应区间(L,R] 中心:M=(L+R+1)/2对于最大值最小化:对应区间[L,R) 中心:M=(L+R)/2#incl...原创 2020-09-29 22:58:19 · 152 阅读 · 0 评论 -
Median POJ - 3579--------------思维(二分)
题意:给定n个数,两两互减取绝对值,一共有n*(n-1)/2个数,问中间值是多少解析:二分答案d先给原序列排序,然后根据公式a[j]-a[i]<=d (j>=i)那么a[j]<=a[i]+d所以我们二分一下a[i]+d 在整个序列的位置,因为(j>=i) 所以还要减去<a[i]的数#include<iostream>#include<algorithm>#include<cstdio>using namespace ..原创 2020-09-29 20:01:22 · 96 阅读 · 0 评论 -
Drying POJ - 3104-------------------思维(二分)
题意:有n件衣服,每件衣服都有ai点水份。现在你可以自然烘干衣服每一分钟减少1点水份,或者你可以选择烘干机,每次烘干k水份,问你最少需要多少时间可以把所有衣服烘干解析:二分枚举答案假设一件衣服烘干需要x分钟,烘干机用了y分钟,那么自然干需要x-y分钟所以: (x-y)+y*k>=a[i]那么: y>=(a[i]-x)/(k-1)假设二分答案为x分钟那么对于<x分钟的都可以置为0,因为他们在x分钟内已经可以自然风干了然后计算y即可,根据y值调动上下限注意的是当k=...原创 2020-09-29 18:16:45 · 126 阅读 · 0 评论 -
D - Alter Altar-----------------------思维(双指针)
题意:给定字符串s s只包括两种字符’R’和’W’ 'W’不能出现在’R’的左边现在给出两种操作1:交换两个字符2.把一个字符更改为’R’或’W’问你至少多少次操作满足 'W’不能出现在’R’的左边解析:双指针 l=1,r=n;如果s[l]==‘W’ ,s[r]=‘R’ 就直接交换 直到满足条件为止#include <bits/stdc++.h>using namespace std;const int N=2e5+1000;char s[N];i...原创 2020-09-29 11:02:07 · 149 阅读 · 0 评论 -
C - Repsept--------------------------思维(大数取模)
题意:给定k,找出7,77,777…77777这种形式的且是k的倍数,最后输出几位数解析:根据最后样例发现位数会在1e6左右,直接爆long long ,所以就想到大数取模了,每次都加一位7然后取模,这样保证答案不会爆long long#include <iostream>using namespace std;const int N=1e6+1000;int mod;int main(){ cin>>mod; int f=0; ...原创 2020-09-29 10:53:40 · 271 阅读 · 0 评论 -
Super Mario HDU - 4417--------------------------思维(主席树裸查询)
题意:给你n个数,每个数都代表着高度。给出m个询问 问[l,r]区间<=H 的个数?解析:主席树裸查询对于<=H 的个数,我们可以二分去找如果找到了H,那么就直接返回R-L两个版本主席树的左子树个数如果H在右子树上,那么说明左子树都是满足条件的,所以必须要加上,然后再向右子树继续二分找到H#include<bits/stdc++.h>using namespace std;const int N=1e5+1000;int a[N];int t,n,m,...原创 2020-09-28 20:17:52 · 93 阅读 · 0 评论 -
不要62--------------------------------思维(数位dp)
解析:预处理:f[i][j]:表示第i位,最高位为 j限制条件:最高位不能选4 第i位不能选6且第i-1位不能选2所以状态转移:f[i][j]+=f[i-1][k] (j!=4 && k!=4 &&(j!=6&&j!=2))数位dp分析:在树上进行决策对于第An-1位0~An-1-1 放到左子树 An-1 放到右子树计算左子树可能的情况 因为不能存在4或者62连起来的。所以用一个last记录 上一位是什么满足 (j!=4&.原创 2020-09-22 18:52:58 · 103 阅读 · 0 评论 -
位运算之谜---------------------------思维(位运算技巧+套路题)
解析:a xor b 相当于是不进位的加法(a&b)<<1 表示加法的进位所以得出公式 a+b == a xor b +(a&b)<<1那么 a xor b ==a+b-2*(a&b)又因为 a+b=x, a&b= y;所以 a xor b = x-2*y;存在两种不可能的存在,第一种就是a xor b <0第二种就是 a xor b 和 a&b 是相互取反的。其他情况只要输出 x-2y 即可#inclu..原创 2020-09-21 15:47:18 · 386 阅读 · 0 评论 -
51NOD1277 字符串中的最大值----------------------思维(kmp)
解析:#include<bits/stdc++.h>using namespace std;const int N=1e6+1000;typedef long long ll;int f[N];ll dp[N];char s[N];int n;void init(){ f[0]=-1; for(int i=2,j=0;i<=n;i++) { while(j&&s[i]!=s[j+1]) j=f[j]; if(s[i]==..原创 2020-09-16 14:20:30 · 92 阅读 · 0 评论 -
51NOD 1686 第K大区间-----------------------思维(二分+双指针+套路题)
解析:套路! 套路! 套路! 一定要谨记!!!!!!!!套路二分枚举答案t。二分check的条件就是判断有多少个区间的众数>t对于check的判断我详细说明一下(利用双指针) 先枚举右端点假设有个序列: 1 2 3 1 4 3假设二分的t=1;那么对于[1,4]区间的众数是num[1]=2 那么有多少个区间满足num[1]=2呢?(这边的套路就要开始了)我们发现[1,5],[1,6]都满足条件,所以当区间的众数>t 则产生的贡献就是n-i+1然后我们需要移动左.原创 2020-09-14 19:57:41 · 132 阅读 · 0 评论 -
D - Redistribution-----------------------思维(dp)
解析:设f[i]:表示用3~i数凑出和为i的方案数f[i]=f[i-3]+f[i-4]+f[i-5]+…+f[i-i]#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=3000;const int MOD=1e9+7;ll f[N];int s;int main(){ cin>>s; f[0]=1; for(int i=3;i<=s;i++..原创 2020-09-14 15:14:50 · 153 阅读 · 0 评论 -
51NOD 3061车--------------------------------思维(最大生成树+倍增)
解析:最大生成树可以求得最大载重路径,因为本题求得最大载重最小是多少,所以我们利用最大生成树找出路径之后,重新建图。然后在新图上倍增求得最大值最小是多少?#include<bits/stdc++.h>using namespace std;const int N=1e5+10;int e[N<<1],ne[N<<1],w[N<<1],h[N],idx;int fa[N],depth[N],q,m,n,u,v;int f[N][20],mi[N..原创 2020-09-13 16:09:58 · 194 阅读 · 0 评论 -
问题 I: Two Famous Companies-----------思维(二分+MST)
题意:给定n个点,m条边,两个点之间用线连接起来。要么是联通的线,要么是移动的线,问必须要选k条电信线的最小生成树是多少解析:再求生成树的时候会遇到两种情况。 cnt为选择电信线的个数第一种 k>cnt 说明我们在选择边的时候,电信线的权值都很大,所以选的很少第二种 k<cnt 说明我们在选择边的时候,电信线权值很小,我们都会优先选择处理的方法就是对于第一种我们可以给电信线权值都减小,使其得到满足对于第二种我们可以给电信线权值都增加,使其得到满足所以我们二分出一个增量mi..原创 2020-09-11 14:05:51 · 173 阅读 · 0 评论 -
模板-----------------------(树同构+重心)
#include <iostream>#include <cstdio>#include <algorithm>#include <unordered_map>#include <vector>#include <map>#include <list>#include <queue>#include <cstring>#include <cstdlib>#include原创 2020-09-01 15:19:07 · 87 阅读 · 0 评论 -
1573 美丽的集合-------------------思维(启发式合并+bitset)
解析:利用启发式合并 nlogn然后利用bitset来维护集合中不同和的次数合并的时候用链表连接同一集合的元素用en[]更新每个集合的最后一个元素是谁#include<bits/stdc++.h>using namespace std;const int N=1005;bitset<100005>f[N];int fa[N],size[N],nx[N],a[N],en[N];int n,m;int find(int x){ if(fa[x]!=x) ...原创 2020-09-01 14:18:32 · 110 阅读 · 0 评论 -
1556 计算-----------------------------思维(默慈金数+组合数学)
解析:本题用到了默慈金数https://www.cnblogs.com/yaoyueduzhen/p/5456530.html如果a[i-1]=1 那么第i位只有两种取值的结果如果a[i-1]>1 那么第i位只有三种取值的结果所以设f[i]:1~x的总的方案数设a[i]:1~x第i位为1的方案数那么递推方程就是f[i]=f[i-1]*3-a[i-2]因为本题求得是(0,1)~(n,x)的总方案数而默慈金数求得是(0,0)~(n,0)的总方案数所以我们用总的方案数-不满足的方案数..原创 2020-09-01 10:58:33 · 162 阅读 · 0 评论 -
问题 E: Songwriter------------------思维(构造)
解析:我们先从后往前遍历求出每个位置的可以取值范围的上下限设up[i]:为第i位置的上限设down[i]:为第i位置的下限分为三种情况第一种情况 a[i]==a[i+1] 那么up[i]=up[i+1],down[i]=down[i+1]第二种情况 a[i]<a[i+1] 那么上限最多up[i]=up[i+1]-1;那么下限down[i]=max(down[i+1]-k,l) 要么就是前一个的下限-k 要么就是l 两者取最大第三种情况 a[i]>a[i+1] 那么下限就是...原创 2020-08-31 13:46:31 · 130 阅读 · 0 评论 -
问题 K: Addition Robot---------------------------思维(线段树维护矩阵乘法)
解析:线段树维护区间矩阵乘法。每个节点都要维护矩阵因为本题有两个公式 A=A+B; B=A+B矩阵A: [AB]\begin{bmatrix}A &B\end{bmatrix}[AB] * [1011]\begin{bmatrix}1 & 0\\ 1 & 1\\\end{bmatrix}[1101] = [A+BB]\begin{bmatrix}A+B & B \end{bmatrix}[A+BB]矩阵B: [AB]\begin{...原创 2020-08-31 12:41:45 · 158 阅读 · 0 评论 -
问题 A: 20190-----------------------思维(组合递推+套路)
解析:由于要按照2019这个顺序递推,所以设‘2’=a ‘0’=b ‘1’=c ‘9’=d递推的方程式a=(a+1)%MODb=(b+a)%MODc=(c+b)%MODd=(d+c)%MOD这样就可以保证顺序的问题不会出错#include <bits/stdc++.h>using namespace std;typedef long long ll;const int MOD=1e9+7;ll a,b,c,d;char s[1000005];int main(..原创 2020-08-29 23:45:16 · 88 阅读 · 0 评论 -
E. Clear the Multiset-------------------思维(分治+套路)
题意:给定n个数,2种操作第一种操作:横切切到底第二种操作:竖切切到底请问最少操作使得n个数为0解析:第一种横切得贡献是每次找到最小的然后切去,然后分治递归下去,详细看代码第二中竖切得贡献是r-l+1;两者取最小值。#include <bits/stdc++.h>using namespace std;const int N=1e5+100;int a[N];int n;int solve(int l,int r){ if(l>r) return..原创 2020-08-26 21:43:02 · 156 阅读 · 1 评论 -
D. Zigzags----------------------------思维(暴力+前缀和)
解析:枚举j和l 然后n^2暴力统计j左边的数出现的次数。枚举l的时候,如果出现a[j]==a[l],就要累加上[j,l]区间的 [1,j-1]这些数出现的次数即可,详细看代码吧,说的不咋地#include <iostream>using namespace std;typedef long long ll;int cnt[3005];int a[3005];int t,n;int main(){ cin>>t; while(t--)..原创 2020-08-26 17:22:43 · 222 阅读 · 0 评论 -
C. Binary String Reconstruction------------------------思维(模拟)
解析:暴力模拟#include <iostream>using namespace std;string s;int t,n,x;int a[200050];int main(){ cin>>t; while(t--) { cin>>s; cin>>x; int n=s.size(); s='0'+s; for(int i=0;i&l..原创 2020-08-26 17:11:28 · 145 阅读 · 0 评论