- 博客(30)
- 收藏
- 关注
原创 51nod 1519 拆方块
水题。。。完全不似5级题的风格。。。。#include using namespace std;const int MAXN=100100;int h[MAXN],dp[2][MAXN];int main(){ int n,i,ans; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) scanf("%d",&h[i]);
2017-02-26 16:33:49 333
原创 51nod 1766 树上的最远点对
线段树套LCA。。。写了近200行对于区间[a,b]和区间[c,d]上各选一点的最大长度,必定等于区间[a,b]内最远点对中的某一点,与区间[c,d]内最远点对中的某一点,这两点的距离。因为有这个性质,就可以在线段树上进行查询了。注意线段树中的合并merge操作,与求答案时的merge操作,有些不同。#include using namespace std;void read(int
2017-02-26 16:23:44 424
原创 51nod 1689 逛街
维护三个堆,分别代表必须取的k个b[i]最小的c[i]=1的商店、还能额外去的商店、暂时不去的商店。从左到右遍历,如果c[i]=1,则加入堆1,否则加入堆2。对堆2和堆3进行维护,保证堆2中的数量在允许范围内#include using namespace std;const int MAXN=100100;int a[MAXN],b[MAXN],c[MAXN];priority_q
2017-02-20 21:21:06 255
转载 51nod 1296 有限制的排列
原题hdu4055#include using namespace std;const int MAXN=5050;const long long mod=1e9+7;int a[MAXN];long long dp[2][MAXN];//dp[i][j]表示i位置填好后,末尾为j的答案 int main(){ long long n,k,l,x,flag,i,j,ans
2017-02-20 15:39:29 320
原创 51nod 1277 字符串中的最大值
KMP算法的玄妙应用。对于起点不为0,终点为i的字符串,如果可以利用d[i]将其对应到起点为0的相等的字符串上。#include using namespace std;const int MAXN=100100;char s[MAXN];int f[MAXN],d[MAXN];void KMP(){ int i,j,len=strlen(s); d[0]=-1; i=
2017-02-20 02:11:53 379
原创 51nod 1463 找朋友
离线+线段树将询问按右端点排序。这样对于(i,j),j必定在当前询问范围内。可以将a[i]+a[j]累积到i上,那样就变成了求区间最大值。#include using namespace std;void read(int&a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch
2017-02-19 23:42:08 469
转载 51nod 1378 夹克老爷的愤怒
设dp[x]表示x节点,能够向上控制几个节点。欠控制时,为负。#includeusing namespace std;const int MAXN=100100;int dp[MAXN];vector vec[MAXN];int ans,k;int dfs(int x,int fa){ int mn=1<<30,mx=-(1<<30); for(int i=0;i<vec
2017-02-17 13:41:25 254
原创 51nod 1199 Money out of Thin Air
利用dfs序(先序遍历),将树对应到一维数组上。然后用线段树更新求解。#includeusing namespace std;const int MAXN=50050;vector vec[MAXN];int sonsum[MAXN],w[MAXN],mp[MAXN],num[MAXN];int tim;struct node{ int l,r; long long ns
2017-02-15 16:21:53 577
转载 51nod 1346 递归
题解:http://blog.csdn.net/u010885899/article/details/48131075#includeusing namespace std;const int MAXN=131173;int a1[110][MAXN],a2[MAXN][100];int main(){ int i,j,n,m,q; for(i=2;i<MAXN;i++)
2017-02-15 16:02:21 223
原创 51nod 1379 索函数
用数学归纳法容易证明出,sor(x)=2^k-1。因此,计算出k即可。对于较小的数,可以直接打表计算。(0~90)对于较大的数,利用斐波那契数的通项公式,忽略其中 ((1-sqrt(5))/2)^n 项,可以计算出答案。#includeusing namespace std;const long long mod=1e9+7;const int limit=90;long l
2017-02-15 15:26:59 262
原创 51nod 1431 快乐排队
将位置也视为一种资源。位置与金币之和,如果存在重复,则sad。#includeusing namespace std;const int MAXN=200200;int a[MAXN];int main(){ int n,i; while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { scanf("%d",&a[i]);
2017-02-15 14:42:26 243
转载 51nod 1257 背包问题 V3
分数规划。#includeusing namespace std;const int MAXN=50050;long long resw,resp;int n,k;struct node{ int w,p; double rate;}a[MAXN];bool cmp(node n1,node n2){ return n1.rate>n2.rate;}bool
2017-02-15 14:06:29 239
原创 51nod 1476 括号序列的最小代价
从左到右贪心。一开始将所有问号都设为右括号。当遇到异常的时候,用优先队列找到改为左括号花费最小的那个,改为左括号。#includeusing namespace std;const int MAXN=50050;long long l[MAXN],r[MAXN];char s[MAXN];int main(){ long long n,i,ans,deep,ll,rr; w
2017-02-14 15:10:08 302
原创 51nod 1394 差和问题
每次修改,都能直接更新答案。数据可以用树状数组或线段树维护。#includeusing namespace std;const int MAXN=200100;char op[MAXN];int discnum;long long disc[MAXN],v[MAXN];long long c[2][2][MAXN],a[MAXN];void update(int num,int
2017-02-12 16:01:43 251
原创 51nod 1204 Parity
如果[st,ed]区间和为偶数,那么前缀和sum[st-1]和sum[ed]的奇偶性相同,可以放入同一集合中。如果[st,ed]区间和为奇数,那么前缀和sum[st-1]和sum[ed]的奇偶性不同,可以将~sum[st-1]和sum[ed]放入同一集合中,sum[st-1]和~sum[ed]放入同一集合中。用并查集可以实现检验和合并操作。#includeusing namespac
2017-02-12 13:17:37 431
原创 51nod 1161 Partial Sums
找规律可以得到,经过k次变换后,a[j]在i上的累加是a[j]*C(i-j+k-1,k-1)。由于k-1不变,因此可以用递推公式C(n+1,m)=C(n,m)*(n+1)/(n-m+1)计算组合数。#includeusing namespace std;const long long mod=1e9+7;const int MAXN=5050;long long a[MA
2017-02-12 11:22:28 305
原创 51nod 1613 翻硬币
开始以为是数论题,求 x*k=(2y+1)*n 时的最小x值。然后WA了。后来发现,每个硬币翻面次数可以不同,比如样例:7 3做法参造曾加老师的解法:https://www.zhihu.com/question/26570175/answer/33312310#includeusing namespace std;int main(){ long long n,k,ans; w
2017-02-10 14:39:27 289
原创 51nod 1668 非010串
dp[i]=2*dp[i-1]-dp[i-2]+dp[i-3]由于有减号,所以矩阵快速幂时,可能会产生负数,要处理掉。#includeusing namespace std;const int siz=3;long long mod=1e9+7;struct mtx{ long long a[siz][siz];}unit;mtx multi(mtx m1,mtx m
2017-02-10 10:35:22 259
原创 51nod 1437 迈克步
单调栈搞一下。时间卡得好紧,printf输出单字符好慢,要用putchar。#includeusing namespace std;void read(int&a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10
2017-02-09 15:07:40 284
原创 51nod 1215 数组的宽度
单调栈搞一下,注意在等于时是否弹出。这里设为从左到右弹出,从右到左不弹出。#includeusing namespace std;const int MAXN=50050;long long a[MAXN],minlef[MAXN],minrig[MAXN],maxlef[MAXN],maxrig[MAXN];struct node{ int pos; long long x
2017-02-09 14:45:22 300
原创 51nod 1495 中国好区间
传说中的尺取法。就两个指针移来移去。。。。#includeusing namespace std;const int MAXN=10001000;long long a[MAXN];int main(){ long long n,k,t,b,c,p,ans,sum,p1,p2,i; while(~scanf("%lld%lld%lld%lld%lld%lld%lld",&n,
2017-02-08 16:41:55 297
原创 51nod 1556 计算
默慈金数的应用在一个“网格”上,若限定“每步只能向右移动一格(可以向右上、右下横向向右),并禁止移动到y=0以下的地方”,则以这种走法用n步从(0,0)移动至(n,0)的可能形成的路径的总数为n的默慈金数。初始状态:M[0]=1M[1]=1M[2]=2递推公式:M[n+1]=((2n+3)*M[n]+3n*M[n-1])/(n+3)直接计算比较困难,可以计算
2017-02-08 15:51:01 294
原创 51nod 1274 最长递增路径
DP题,不过写得有点奇怪。。。将边按边权值排序,dp[x]表示走到x点为止的最长路径。然后不断转移。需要注意的是边权值相等时,应该从边权值更小的地方转移,而非边权值等价的地方转移。每个节点打个 修改时间标记,并记录修改之前的数据,就可以解决这个问题。#includeusing namespace std;const int MAXN=50050;int dp[MAXN],tim[MAX
2017-02-08 12:52:41 457
原创 51nod 1140 矩阵相乘结果的判断
加读入优化,或者等式两边乘以一个列向量,验证是否成立。#includeusing namespace std;void read(int&a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
2017-02-08 10:51:36 376
原创 51nod 1678 lyk与gcd
记录每个i的素因子,以及每个i的倍数j的a[j]之和。容斥一下。由于只考虑是否互质,因此容斥时考虑素因子即可。#includeusing namespace std;const int MAXN=100100;vector fac[MAXN];int sum[MAXN],npri[MAXN],a[MAXN];int cal1(int x){ int ret=0; while
2017-02-08 10:13:53 351
原创 51nod 1737 配对
对于一条边来说,其理论最大贡献值为z*min(sonsum[lefnode],sonsum[rignode])。如果考虑所有配对都经过树的重心,那么可以做到所有边的贡献值都为理论最大贡献值。dfs计算下即可。#includeusing namespace std;const int MAXN=100100;struct edge{ long long x,w;}etmp;ve
2017-02-07 16:19:33 251
原创 51nod 1603 限高二叉排列树
挺经典的DP。dp[i][j]表示高度为i,节点数为j时的方案总数。#includeusing namespace std;int main(){ long long n,h,i,lef,rig,k,ans; long long dp[40][40]; while(~scanf("%lld%lld",&n,&h)) { memset(dp,0,sizeof(dp));
2017-02-07 15:34:59 315 1
原创 51nod 1535 深海探险
BFS跑一下就好了,判断下是否只有一个环。需要注意的是,还需判断是否有孤立点的存在。#includeusing namespace std;void read(long long &a){ char ch;while(!((ch=getchar())>='0')&&(ch<='9')); a=ch-'0';while(((ch=getchar())>='0')&&(ch<
2017-02-07 14:44:58 237
转载 51nod 1781 Pinball
昨天看到时,这题还是三级题的。然后各种想不出。大佬说DP+线段树+离散,想了想可以做。然后今天改成了五级题了。。。L[i]表示球从1位置落下,最后从第i个漏斗出去的情况下,的最小费用。R[i]表示球从n位置落下,最后从第i个漏斗出去的情况下,的最小费用。那么答案就是min(L[i]+R[i]-d[i])。动态转移方程:L[i]=min{L[j] | a[i]≤c[j]≤b[i]}
2017-02-07 13:29:32 377 1
原创 51nod 1548 欧姆诺姆和糖果
XJB暴力跑一下。。。。感觉应该有更好的做法#includeusing namespace std;int main(){ long long c,hr,wr,hb,wb,i,ans,limit=10000000; while(~scanf("%lld%lld%lld%lld%lld",&c,&hr,&hb,&wr,&wb)) { ans=0; if(c/wb<limit
2017-02-07 00:56:13 354
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人