摘要:
虽然数很大,但是这40个数的公倍数一共才4万多个。这里用到STL会方便很多,map[i]里存放了从1~i能组成的公倍数有哪些以及每个数有多少种组成方法。 预处理一遍打个表然后每次O(n)的遍历一遍,否则会超时。 #include <string.h>#include <stdio.h>#include <map>typedef __int64 LL;int n,cas;LL m,ans;std::map<LL,LL> mp[41];std::map<LL,LL>::iterator it;LL gcd(LL a,LL b){ retu 阅读全文
posted @ 2012-08-27 23:41
Burn_E
阅读(167)
评论(0)
推荐(0)
摘要:
简单线段树,开根号开几次这个数就为1了,之后再对其开根号就没有意义了。当一个区间全部为0或者1时就没有必要再去跟新这个区间了。 #include <string.h>#include <stdio.h>#include <math.h>#define lson l,m,p<<1#define rson m+1,r,p<<1|1#define calm (l+r)>>1#define MAXN 100005typedef __int64 LL;int n,q,cas=1,tu,tv,tq;LL sum[MAXN<< 阅读全文
posted @ 2012-08-27 23:35
Burn_E
阅读(138)
评论(0)
推荐(0)
摘要:
一开始看范围特别小就写搜索了。。。结果自己随便出了个4*4就过不了了。。 其实就是状态压缩DP,求哈密顿回路要多少条,只是要注意判断两点是否可以划线就可以了。 #include <stdio.h>#include <string.h>#include <algorithm>typedef __int64 LL;int n,m,tot;int mz[25],bet[25][25][25],full;int zero[16],zeros,hzero[25],lowb[65536];LL d[16][65536],ans;int cant(int st,int e 阅读全文
posted @ 2012-08-27 23:24
Burn_E
阅读(215)
评论(0)
推荐(0)
摘要:
ai取值范围0~1,xi取值范围0~3,所以最后异或的结果不会超过两位二进制。所以可以用一个60位的数保存30个式子的值,然后m的范围是小于22,二分一下就可以了,4^11=4*10^6,结果存下来排个序然后二分找一下就可以了。 #include <stdio.h>#include <string.h>#include <algorithm>typedef __int64 LL;int cas,n,m,ai[35][30],si[30][4];LL ans,tmp[1<<22+2];int sum[1<<22+2];int size, 阅读全文
posted @ 2012-08-27 23:14
Burn_E
阅读(296)
评论(0)
推荐(0)
摘要:
简单二分,最大射击距离是必然能达到的,只要在能到达最大距离的瞬间就立刻射击可以保证时间最短。 #include <string.h>#include <stdio.h>#include <math.h>double xx1,yy1,xx2,yy2,lx,ly,vd,vb,l;double sqr(double x){return x*x;}double getdis(double xx1,double yy1,double xx2,double yy2){ return sqrt(sqr(xx1-xx2)+sqr(yy1-yy2));}int canreac 阅读全文
posted @ 2012-08-27 23:08
Burn_E
阅读(148)
评论(0)
推荐(0)
摘要:
看上去很复杂的一道博弈,其实只要稍微分析就会发现情况其实很少很简单。。 斌牛的解释十分详细,我就不赘述了。。http://www.cnblogs.com/staginner/archive/2011/09/10/2173317.html 这里采用数组存储顺序可以大大减少代码的复杂程度,incs存储的是占用这个格子是会给自己留下稳定占位的个数,-1代表给对手留下了一个稳定占位。 #include<stdio.h>#include<string.h>/* Alice:15>3~6>11~14>7~8>9~10>1 Bob :15>3~6& 阅读全文
posted @ 2012-08-27 23:01
Burn_E
阅读(199)
评论(0)
推荐(0)
摘要:
一开始想的很复杂,其实只要离散化一下就行了,炸x的时候将对应的y都-1,然后统计对应的y的时候将对应的已经炸掉的点减去即可。 #include <stdio.h>#include <string.h>#include <algorithm>#define MAXN 100005struct pnt{ int x,y;}px[MAXN],py[MAXN];bool cmpx(const pnt& a,const pnt& b){ return a.x<b.x||a.x==b.x&&a.y<b.y;}bool cmpy 阅读全文
posted @ 2012-08-27 22:39
Burn_E
阅读(238)
评论(0)
推荐(0)
摘要:
给出如下图形,其中23个格子填有1~23,移动规则与八数码相同,给定始终态,问是否可达。 首先八个角的数字是不可能移动出去的,所以先对八个角进行判断,如果为空格则和附近格子的数进行交换,问题转化为16数码问题。和八数码类似,可以用奇偶性来判断两个状态是否可达,不同的是,将一个数上下移动会影响的整体的奇偶性,一个很好的方法就是"弓"字行统计,这样移动后奇偶性就不会改变了。#include <stdio.h>#include <string.h>int cas,a[25],b[25];//八个顶点必须相同,若为0和相邻的置换int p1[]={0,1,2 阅读全文
posted @ 2012-08-27 22:30
Burn_E
阅读(284)
评论(0)
推荐(0)
摘要:
最小树形图模版题,学习了一下最小树形图。 三步走,找最小入弧,找有向环,缩环为点。#include <string.h>#include <stdio.h>#include <stdlib.h>#define INF 0x3f3f3f3f#define MAXN 1001struct edge{ int u,v,w;}e[MAXN*MAXN];int n,x,y,z,es,k,tt;int pnt[MAXN][3];int dist(int p1,int p2){ int ret=0; for(int i=0;i<3;i++)ret+=abs(pnt[ 阅读全文
posted @ 2012-08-27 22:15
Burn_E
阅读(223)
评论(0)
推荐(0)
摘要:
给定一棵树,求出当x为根时y的最小儿子和最小后代各是多少。 一道中等的树形DP,首先以1为根进行DP可以求出每个节点的最小儿子和最小后代。只有当x为y的孩子时才需要讨论,否则直接输出前面DP的结果即可,这里画个图就可以看出来,下面只讨论x为y的孩子的情况。 如果y的最小儿子是x的祖宗节点,那这时该最小儿子已经变成了y的父亲,在选取最小儿子时不能在考虑这个点,应该换选次小儿子,所以每个点的次小儿子也要在DP时预处理出来,另外,这时y的原父亲在新树中已经变成了y的儿子,所以在选取最小儿子时要考虑父节点。至于最小后代,如果y不是根节点,那么最小后代必然是根节点1了,如果y节点是根节点,就先找... 阅读全文
posted @ 2012-08-27 22:08
Burn_E
阅读(228)
评论(0)
推荐(0)
摘要:
以为是什么复杂的几何题,结果边长是平行于坐标轴的,一下子就变成大水题了。找了半天也没发现题目哪写了边长平行于坐标轴。。。 数据范围小,n次枚举*nlogn排序,暴力枚举就可以过。#include <stdio.h>#include <string.h>#include <algorithm>#define MAXN 1005int n,r;struct pnt{ int x,y;}p[MAXN],p2[MAXN];bool cmpx(const pnt& p1,const pnt& p2){ return p1.x<p2.x;}bool 阅读全文
posted @ 2012-08-27 21:53
Burn_E
阅读(119)
评论(0)
推荐(0)
摘要:
水题。虽然求第K大值的方法有很多种,各种树都可以,但这题只要一个元素个数固定的堆就可以了。。。。 #include <stdio.h>#include <string.h>#include <queue>#define MAXN 1000000int n,k,num;char op[5];int main(){//freopen("test.in","r",stdin); while(scanf("%d%d",&n,&k)!=EOF){ std::priority_queue< 阅读全文
posted @ 2012-08-27 21:46
Burn_E
阅读(120)
评论(0)
推荐(0)
摘要:
敌人会在图中加一条边,你的任务是摧毁一条边,使敌人所在块不连通,求最小的花费。 首先摧毁双联通分量中的边是没有意义的,这个很容易理解。于是对原图进行缩点,行成一棵树,敌人加某一条边后会形成一个环,摧毁这个环中的点是没有意义的,显然对于敌人来说连接叶子节点形成的环会最大。如果这个环不包含最小边,那么去掉最小边后图就不连通了,所以敌人加边后生成的环必然包括最小边。以这个最小边的两个顶点为根生成两棵树,敌人选取了某个叶子节点后,那么选择从这个叶子节点到根节点路径上的边去摧毁都是毫无意义的。对每个节点维护两个值,一个是以该节点为根节点的子树中最小边权,一个是除去这个包含最小边权的子树外的其它子树... 阅读全文
posted @ 2012-08-27 21:44
Burn_E
阅读(220)
评论(0)
推荐(0)
摘要:
一道简单的二分。 #include <string.h>#include <stdio.h>#include <algorithm>#define MAXN 500005int l,n,m;int d[MAXN];int cant(int x){ int now=0,ans=0; for(int i=1;i<=n;i++){ if(d[i]-d[i-1]>x)return 1; if(d[i+1]-d[now]>x)now=i,ans++; } //最后一步要跳到终点 if(now<n)ans++; return ans>m.. 阅读全文
posted @ 2012-08-27 21:13
Burn_E
阅读(147)
评论(0)
推荐(0)
摘要:
树形背包的变形,要特殊考虑当用一个机器人遍历一棵子树的情况。 /*d[i][k]表示节点i用k个机器人探索的最小花费跟树型背包问题差不多d[u][k]=d[u][k-i]+d[v][i]+i*w表示给当前已遍历的子树以及父节点k-i个机器人,给当前正在遍历子树i个机器人注意也可以把k个机器人全部给已遍历子树,d[v][0]实际上相当于用一个机器人遍历完再走到父节点所以这种情况下d[u][k]=d[u][k]+d[v][0]+2*w*/#include <stdio.h>#include <string.h>#define MAXN 10005#define MAXK 1 阅读全文
posted @ 2012-08-27 21:09
Burn_E
阅读(139)
评论(0)
推荐(0)
摘要:
问小于n的数里n/phi(n)最大的数是多少。 由欧拉函数的性质可得n/phi(n)=n/(n*(1-1/p1)*(1-1/p2)...*(1-1/pn))=1/((1-1/p1)*(1-1/p2)...*(1-1/pn)),其中p1~pn为n的质因数。 可见n的质因数越多,n/phi(n)的值越大,所以令n为连续素数的乘积即可。 #include <string.h>#include <stdio.h>struct bign{ int s[205],len; bign(){memset(s,0,sizeof s);len=1;} bign(char *str){*.. 阅读全文
posted @ 2012-08-27 21:06
Burn_E
阅读(145)
评论(0)
推荐(0)
摘要:
简单的类LIS问题,按长和宽排序然后DP。注意两个问题即可,一是要规定长的边为长,短边为宽,二是排序时要将要求较少的块放在后面。 #include <stdio.h>#include <string.h>#include <algorithm>#define MAXN 1005typedef __int64 LL;struct block{ int ai,bi,ci,di; bool operator <(const block& b)const{ if(ai!=b.ai)return ai<b.ai; if(bi!=b.bi)retur 阅读全文
posted @ 2012-08-27 20:51
Burn_E
阅读(170)
评论(0)
推荐(0)