雕刻时光

just do it……nothing impossible
随笔 - 547, 文章 - 0, 评论 - 82, 阅读 - 86万
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

07 2011 档案

摘要:有向图强连通分量的Tarjan算法有个比较好的讲解http://www.byvoid.com/blog/scc-tarjan/zh-hans/学习一下,贴个比较好的模板View Code #include <iostream>#include <stack>using namespace std; const int MAXN = 10000 + 10; // 点的最大数量const int MAXM = 50000 + 10; // 边的最大数量 // 假设对边u-->vstruct EDGE{ int v; // 从u点出发能到达的点v int next; / 阅读全文

posted @ 2011-07-29 16:07 huhuuu 阅读(258) 评论(0) 推荐(0) 编辑

摘要:开始用floyd可以,不过时间太慢了(N*N*N)后来枚举牛做DFS连通性检验,O(N*M)View Code #include<stdio.h>#include<string.h>int net[1009][1009];bool visit[1009];int cow[109];int c[1009];void dfs(int x){ c[x]++; visit[x]=1; for(int i=1;i<=net[x][0];i++) { if(!visit[net[x][i]]) dfs(net[x][i]); }}int main(){ int k,n,m; 阅读全文

posted @ 2011-07-29 10:03 huhuuu 阅读(244) 评论(0) 推荐(1) 编辑

摘要:暴力枚举下,可以发现规律View Code #include<stdio.h>long long a[1000009];int main(){ a[1]=1; int n,i,id=1; while(scanf("%d",&n)!=EOF) { id=1; for(i=2;i<=n;i+=2) { a[i]=a[i+1]=(a[i-1]+a[id])%1000000000; id++; } printf("%lld\n",a[n]); } return 0;} 阅读全文

posted @ 2011-07-28 18:19 huhuuu 阅读(287) 评论(0) 推荐(0) 编辑

摘要://有N个数,对于任一个数来说,其它的数有多少个是它的约数可以先把数存储在struct data{ int v;//该数字出现的次数 int add;//该数字的约数总数}node[1000009];枚举 存在的node[],在此基础上更新它的公倍数即可。。。View Code 阅读全文

posted @ 2011-07-28 15:40 huhuuu 阅读(498) 评论(0) 推荐(0) 编辑

摘要:好久没写搜索的题目了500*500深搜肯定不行求最小步长,BFS,坐标有(-500,500),+500搞定ps:把状态量写成 i, j一类的,容易不混淆坐标。。。以前用X,Y表示一直要与数学里的坐标搞错的,囧写完由于用c提交CE了一次,cpp提交,一次AC...View Code #include<stdio.h>#include<iostream>#include<queue>#include<string.h>using namespace std;bool hash[1009][1009];int diri[4]={0,-1,0,1};in 阅读全文

posted @ 2011-07-28 14:52 huhuuu 阅读(641) 评论(0) 推荐(0) 编辑

摘要:感觉这种从左向右统计的题目都可以用到栈来优化单调栈,从左向右扫ps:STL里的栈是比较快的,自己是、手写的栈效率跟它差不多啊。。。View Code #include<stdio.h>#include<iostream>#include<stack>using namespace std;int a[80009]; int main(){ int n; while(scanf("%d",&n)!=EOF) { int i; for(i=0;i<n;i++) scanf("%d",&a[i]); s 阅读全文

posted @ 2011-07-28 13:52 huhuuu 阅读(306) 评论(0) 推荐(0) 编辑

摘要:暴力亦可过,同没意思。。。有个O(n)的算法从左向右扫{while{if(栈顶元素.h>当前元素.h) 入队,更新栈顶元素对应的牛的V ,结束while循环else 出队}直到队列为空}再从右向左View Code #include<stdio.h>#include<iostream>#include<stack>using namespace std;struct data{ int h,v,no;}node[50009];int all[50009];int main(){ int n; while(scanf("%d",&am 阅读全文

posted @ 2011-07-27 21:31 huhuuu 阅读(363) 评论(0) 推荐(0) 编辑

摘要:暴力也可过,不过太没意思先排序:如41 3 5 8(3-1)*(1*3)+(5-3)*(2*2)+(8-5)*(3*1)规律发现了吧。。。View Code #include<stdio.h>#include<iostream>#include<algorithm>using namespace std;int a[10009];int main(){ int n; while(scanf("%d",&n)!=EOF) { int i,j; for(i=0;i<n;i++) { scanf("%d",&a 阅读全文

posted @ 2011-07-27 17:07 huhuuu 阅读(316) 评论(0) 推荐(0) 编辑

摘要:比较好的贪心题也学会了优先队列吧思路:现对开始时间升序排序(再一次领教到了排序降维的意义!!!)优先队列里放add(第几次stall),rr(结束时间)在把第一个放到优先队列,第二个数与优先队列顶部进行比较若第二个数结束时间>优先队列顶部结束时间,则更新该顶部时间否则第二个数加到该优先队列里View Code #include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>using namespace std;int r 阅读全文

posted @ 2011-07-27 15:43 huhuuu 阅读(296) 评论(0) 推荐(0) 编辑

摘要:解题的思想用到了 类似最长递增子序的方法,先按起始时间升序排序,不断更新,到某点(包括改点)最大值排序的目的:可以把看似二维的区间降到一维!!!!O(n*n)dp[i]=max(dp[i],dp[j]+node[i].v);dp[i]放着的是包括i点,最大的价值View Code #include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;struct data{ int b,e; int v;}node[1009];int 阅读全文

posted @ 2011-07-27 10:09 huhuuu 阅读(359) 评论(0) 推荐(0) 编辑

摘要:想下递归过程注意位运算优先级小,加括号View Code #include<stdio.h>int k;int dfs(int left){ if((left-k)<=1||((left-k)%2)==1) { return 1; } return dfs((left-k)>>1)+dfs(left-((left-k)>>1));}int main(){ int n; while(scanf("%d%d",&n,&k)!=EOF) { printf("%d\n",dfs(n)); }} 阅读全文

posted @ 2011-07-26 16:06 huhuuu 阅读(263) 评论(0) 推荐(0) 编辑

摘要:N*NView CodeNlog(N)觉得这个更接近于贪心的思想二分查找,可以更新则不断把a[]中的子数更新小,否则增加a[]View Code #include<stdio.h>int s[5009];int a[5009];int n;int lis(){ int l,r,mid,len=1; a[1]=s[1]; for(int i=2;i<=n;i++) { l=1,r=len; while(l<=r) { mid=(l+r)>>1; if(a[mid]<s[i])l=mid+1; else r=mid-1; } a[l]=s[i]; if(l 阅读全文

posted @ 2011-07-26 09:42 huhuuu 阅读(369) 评论(0) 推荐(0) 编辑

摘要:构造矩阵,题比较水不解释了View Code #include<stdio.h>#include<string.h>int mod;//矩阵中间数求模int n;int a[19];struct data{ int map[11][11];};data matrix(data a,data b)//矩阵乘法{ int i,j,k; data re; for(i=0;i<n;i++) { for(j=0;j<n;j++) { int all=0; for(k=0;k<n;k++) ... 阅读全文

posted @ 2011-07-25 20:24 huhuuu 阅读(303) 评论(0) 推荐(0) 编辑

摘要:结构体里尽量不要放int64不然容易爆内存View Code #include<stdio.h>#include<string.h>int mod;int n;struct data{ int map[30][30];};data res;data add(data a,data b)//矩阵加{ data re; int i,j; for(i=0;i<n;i++) { for(j=0;j<n;j++) { re.map[i][j]=(a.map[i][j]+b.map[i][j])%mod; } ... 阅读全文

posted @ 2011-07-25 16:56 huhuuu 阅读(224) 评论(0) 推荐(0) 编辑

摘要:矩阵A^1+A^2+A^3...A^6=(A^2+ret)*(A^1+A^2+A^3);=(A^2+ret)*(A*(ret+A)+A^3);如果是A^1+A^3+A^5...=A*(ret+A^2+A^4..)即把A^2+A^4...看成A^k+A^2k...View Code #include<stdio.h>#include<string.h>__int64 mod;__int64 n;struct data{ __int64 map[3][3];};data res;data add(data a,data b)//矩阵加{ data re; int i,j; 阅读全文

posted @ 2011-07-25 16:11 huhuuu 阅读(168) 评论(0) 推荐(0) 编辑

摘要:View Code #include<stdio.h>#include<string.h>constint mod=9973;//矩阵中间数求模int n;struct data{ int map[19][19];};data matrix(data a,data b)//矩阵乘法{ int i,j,k; data re; for(i=0;i<n;i++) { for(j=0;j<n;j++) { int all=0; for(k=0;k<n;k++) { ... 阅读全文

posted @ 2011-07-25 10:35 huhuuu 阅读(508) 评论(0) 推荐(0) 编辑

摘要:裸的矩阵乘法注意点:步数为0时,A,B点相同时路有1条步数为0时,A,B点不相同时路有条0条View Code #include<stdio.h>#include<string.h>struct data{ int map[29][29];}mat[29];int main(){ int n,m; while(scanf("%d%d",&n,&m),n||m) { int i,j; memset(mat,0,sizeof(mat)); for(i=0;i<n;i++) { for(j=0;j<... 阅读全文

posted @ 2011-07-25 09:16 huhuuu 阅读(465) 评论(0) 推荐(1) 编辑

摘要:转移方程:add[i]放到i的和f[i]到i为止最大值f[i]=max(f[i],f[i-2*j]+add[i-j]-add[i-2*j]);DP不是很会啊,加油。。。View Code #include<stdio.h>int f[10009];int add[10009];int max(int a,int b){if(a>b)return a;else return b;}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int i,j; add[0]=0; for(i=1; 阅读全文

posted @ 2011-07-23 16:34 huhuuu 阅读(454) 评论(0) 推荐(0) 编辑

摘要:题目种涉及到区间的查询,想到线段树View Code #include<stdio.h>int tmin=10000009,tmax=0;struct data{ int l,r; int min,max;}node[9950009];int fmax(int a,int b){ return a>b?a:b;}int fmin(int a,int b){ return a<b?a:b;}void build(int ll,int rr,int n){ node[n].l=ll; node[n].r=rr; node[n].max=-1; node[n].min=100 阅读全文

posted @ 2011-07-23 08:59 huhuuu 阅读(413) 评论(0) 推荐(0) 编辑

摘要:题意:1,2,3,4,5。。。加上加减号使数字和为N,数字越少越好View Code #include<stdio.h>int main(){ int n; scanf("%d",&n); if(n==0) { printf("0\n"); return 0; } if(n<0)n=-n; int i; for(i=1;i<99999;i++) { __int64 all=(i+1)*i/2; if(all==n) { printf("%d\n",i); break; } else if(all> 阅读全文

posted @ 2011-07-22 14:00 huhuuu 阅读(144) 评论(0) 推荐(0) 编辑

摘要:做了一点,差不多总结下最大二分匹配有这么几种题目最大匹配:匈牙利算法最小点覆盖:等于最大匹配数最大独立集:顶点数-最大匹配数最小边覆盖:顶点数-最大匹配数(最小边覆盖有边不可相交,边可以相交,边可以相交时可以用floyd判断图的连通性,有环存在要缩点)二分图的必须边:先匈牙利最大匹配,在枚举去掉最大匹配的边,再匈牙利最大匹配,看是否还是等于原来的最大匹配数。。。若不是则为必须边最优匹配 KM算法比较死可见构图的重要性,特别是:对应关系的建立:把看似没联系的问题用二分图建立关系拆点:把一个点分成多个点,使二分图建立 阅读全文

posted @ 2011-07-22 09:26 huhuuu 阅读(206) 评论(0) 推荐(0) 编辑

摘要:左集合毫无疑问n右集合如何构造就可以建立良好的对应关系3 41 100 100 10099 1 99 9998 98 1 98可以拆点建立该图就是把j点拆成3份对应关系就出来了1 2 3 100 200 300 100 200 300 100 200 30099 198 297 1 2 3 99 198 297 99 198 29798 196 294 98 196 294 1 2 3 98 196 294View Code #include<stdio.h>#include<string.h>#define MAXN 2509#define inf 100000000 阅读全文

posted @ 2011-07-22 09:11 huhuuu 阅读(235) 评论(0) 推荐(0) 编辑

摘要:View Code #include<stdio.h>#include<math.h>#include<string.h>#define MAXN 109#define inf 1000000000#define _clr(x) memset(x,0xff,sizeof(int)*MAXN)int mat[109][109];int match1[MAXN];int match2[MAXN];struct data{ int fi,fj; }H[109];struct data1{ int fi,fj;}M[109];int KM(int m,int n,i 阅读全文

posted @ 2011-07-21 15:20 huhuuu 阅读(286) 评论(0) 推荐(0) 编辑

摘要:一开始没看到You should notice that the roads of two different robots may contain some same point. WA了好几次它是说如果1-22-3那么1-3图的传递性可以用floyd快速求解View Code #include<stdio.h>#include<math.h>#include<string.h>int g,m;bool map[509][509];int mark[509];bool flag[509];bool dfs(int x){ int i; for(i=1;i& 阅读全文

posted @ 2011-07-21 10:10 huhuuu 阅读(537) 评论(0) 推荐(0) 编辑

摘要:路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联最小路径覆盖就是找出最小的路径条数,使之成为P的一个路径覆盖.最小路径覆盖=顶点数-最大匹配数(貌似与最大独立集同)建图:集合A,B分别放顶点P,P'如果出租车在X点可以Y点,则map[x][y]=1;//因为是X->Y,而题意Y显然无法到X,所以单向图附上测试数据:1500:00 0 0 1 100:02 1 1 2 200:06 2 2 3 300:03 1 1 4 400:12 4 4 5 5输出2View Code #include<stdio.h>#include& 阅读全文

posted @ 2011-07-21 09:21 huhuuu 阅读(1216) 评论(0) 推荐(0) 编辑

摘要:题意是判断二分图的边是否唯一先最大二分匹配下枚举 A集合的点所连接的边 删除在最大二分匹配下看匹配数是否与没删前一样,若不一样,则说明该边是唯一边View Code #include<stdio.h>#include<string.h>bool map[59][59];int mark[59];int rmark[59];bool flag[59];int m,g;struct data{ int minx,miny,maxx,maxy;}node[59];struct data1{ int x,y;}point[59];struct data2{ char str; 阅读全文

posted @ 2011-07-20 19:26 huhuuu 阅读(166) 评论(0) 推荐(0) 编辑

摘要:最大独立集: 在N个点的图G中选出m个点,使这m个点两两之间没有边,求m最大值。如果图G满足二分图条件,则可以用二分图匹配来做。最大独立集点数 = N - 最大匹配数。将孩子看成二分图里的 A,B集若孩子a喜欢的动物号是孩子b喜欢的动物号则连边,因为A,B集是同类,无向图map[a][b]=1;map[b][a]=1;实际上就是最大独立集=顶点数-最大匹配数/2View Code #include<stdio.h>#include<string.h>bool map[509][509];int mark[509];bool flag[509];int m;char A[ 阅读全文

posted @ 2011-07-20 15:45 huhuuu 阅读(848) 评论(2) 推荐(0) 编辑

摘要:裸题。。。View Code #include<stdio.h>#include<string.h>bool map[109][109];int mark[109];bool flag[109];int m;bool dfs(int x){ int i; for(i=1;i<=m;i++) { if(map[x][i]==0||flag[i]) continue; flag[i]=1; if(mark[i]==0||dfs(mark[i])) { mark[i]=x; return 1; } } return 0;}int main(){ int i,g,k,j; 阅读全文

posted @ 2011-07-20 13:52 huhuuu 阅读(148) 评论(0) 推荐(0) 编辑

摘要:主要难点在与拆点举个例子:3. . .X . X. X .在行上拆成1 1 10 2 03 0 4列上拆成1 3 40 3 02 0 5就行了。。。后面一样View Code #include<stdio.h>#include<string.h>bool map[20][20];int hash[5][5];int row[5][5];int lie[5][5];int mark[20];bool flag[20];int m;bool dfs(int x){ int i; for(i=1;i<=m;i++) { if(map[x][i]==0||flag[i]) 阅读全文

posted @ 2011-07-20 11:10 huhuuu 阅读(179) 评论(0) 推荐(0) 编辑

摘要:把行列转化为二分图根据König定理:二分图最小点覆盖数 = 最大匹配数View Code #include<stdio.h>#include<string.h>bool map[505][505];int mark[505];bool flag[505];int m;bool dfs(int x){ int i; for(i=1;i<=m;i++) { if(map[x][i]==0||flag[i]) continue; flag[i]=1; if(mark[i]==0||dfs(mark[i])) { mark[i]=x; return 1; } 阅读全文

posted @ 2011-07-20 08:31 huhuuu 阅读(221) 评论(0) 推荐(0) 编辑

摘要:View Code #include<stdio.h>#include<string.h>bool map[505][505];int men[505];bool hash[505];int m;bool dfs(int x){ int i; for(i=1;i<=m;i++) { if(map[x][i]==0||hash[i]) continue; hash[i]=1; if(men[i]==0||dfs(men[i])) { men[i]=x; return 1; } } return 0;}int main(){ int i,g,k; int count; 阅读全文

posted @ 2011-07-19 15:02 huhuuu 阅读(226) 评论(0) 推荐(0) 编辑

摘要:比较好的数论d(6543) = d(6 + 5 + 4 + 3) = d(18) = 9、其实d(n)=n%9all+=a[i]*a[j]*a[(i*j)%9];//是统计(i*j))%9==((k)%9)的次数 __int64 add=0; for(i=1;i<=n;i++) { for(j=i;j<=n;j+=i) { add++; } }//统计((i*j)%9==((k)%9))&&(i*j)==k的次数先减一下就是((i*j)%9==((k)%9))&&(i*j)!=k的次数View Code #include<stdio.h> 阅读全文

posted @ 2011-07-19 10:10 huhuuu 阅读(294) 评论(0) 推荐(0) 编辑

摘要:给你电影院长宽K然后给你N给问题请你分配位子要求权值最小在权值相同时按I取最小还是相同就按J最小暴力搜索下就行不难,但是用等差公式算时没考虑周到。。。View Code #include<stdio.h>#include<math.h>#include<string.h>int ll[1009];bool map[109][109];int main(){ int n,len; memset(map,0,sizeof(map)); scanf("%d%d",&n,&len); int i2=(len+1)/2; int j 阅读全文

posted @ 2011-07-18 20:11 huhuuu 阅读(382) 评论(0) 推荐(0) 编辑

摘要:先按s从小到大排序若相同再按E从大到小在点相同时要特殊处理View Code #include<cstdio>#include<iostream>#include<algorithm>using namespace std;int n;int tree[200009];int all[200009];int temp[200009];struct data{ int l,r; int no;}node[200009];int lowbit(int x){ return x&(-x);}void updata(int x,int c){ int i; 阅读全文

posted @ 2011-07-16 15:53 huhuuu 阅读(189) 评论(0) 推荐(0) 编辑

摘要:题意:统计左下方的星星数容易出现TLE的情况因为0<=X,Y<=32000x=0时,因为0&(-0)=0,所以会在树状数组里出现死循环解决办法是每个x++;由于y是升序的,故不用考虑,就统计X即可View Code #include<cstdio>#include<iostream>using namespace std;int n;int tree[50009];int add[50009];int a[50009];int lowbit(int x){ return x&(-x);}void updata(int x,int c){ in 阅读全文

posted @ 2011-07-15 17:01 huhuuu 阅读(172) 评论(0) 推荐(0) 编辑

摘要:由于点范围比较大所以用离散化一下点如2 1 3n=3然后,在树状数组里放依次放入updata(2,1),统计sum(n)-sum(1),updata(1,1),统计sum(n)-sum(3)View Code 阅读全文

posted @ 2011-07-15 15:40 huhuuu 阅读(129) 评论(0) 推荐(0) 编辑

摘要:输入n然后n个数字输出需要换几次View Code #include<cstdio>#include<iostream>#include<algorithm>using namespace std;struct data{ int val; int no; int N;}a[500009];int hash[500009];int cmp(data a,data b){ return a.val<b.val;}int cmp1(data a,data b){ return a.no<b.no;}int main(){ int n; while(s 阅读全文

posted @ 2011-07-15 13:59 huhuuu 阅读(246) 评论(0) 推荐(0) 编辑

摘要:求最小排序交换次数贪心做View Code #include<stdio.h>#include<algorithm>#include<iostream>using namespace std;int b[1009],a[1009];int min(int a,int b){ if(a>b)return b; else return a;}int max(int a,int b){ if(a>b)return a; else return b;}int main(){ int n; int add[6]; while(scanf("%d& 阅读全文

posted @ 2011-07-15 11:17 huhuuu 阅读(348) 评论(0) 推荐(0) 编辑

摘要:离散化,对区间离散化31 101 36 10染色3会变成1 41 23 4染色2所以要区间*22 82 46 8染色3错的,却AC的代码View Code对的代码,虽然被烂数据判错View Code 阅读全文

posted @ 2011-07-15 09:53 huhuuu 阅读(145) 评论(0) 推荐(0) 编辑

摘要:前面一直TLE,最终原因是因为没有将查找的压倒O(log(N))查找更新都需要遗传结构!!!View Code #include<stdio.h>structdata{intl,r;__int64all;//开始单点更新__int64hou;}node[300009];inta[100009];voidbuild(intll,intrr,intn){node[n].l=ll;node[n].r=rr;node[n].hou=0;if(ll==rr){node[n].all=a[rr];}if(ll==rr)return;intmid=(ll+rr)>>1;build(l 阅读全文

posted @ 2011-07-14 15:35 huhuuu 阅读(281) 评论(0) 推荐(0) 编辑

摘要:先暴力统计开始时逆序数对数量add再枚举a[i]add=add+(n-1)-2*a[i];记录最小View Code #include<stdio.h>int a[60009];int main(){int n;while(scanf("%d",&n)!=EOF){int i;for(i=1;i<=n;i++){scanf("%d",&a[i]);}int j;int add=0;for(i=1;i<n;i++){for(j=i+1;j<=n;j++){if(a[i]>a[j])add++;}}int 阅读全文

posted @ 2011-07-13 08:59 huhuuu 阅读(344) 评论(0) 推荐(0) 编辑

摘要:在单纯的更新结点时,是不需要用到遗传结构的在区间的更新时,会用到遗传结构View Code #include<stdio.h>#include<string.h>struct data{int l,r,val;}st[200009];void build(int ll,int rr,int n){st[n].l=ll;st[n].r=rr;st[n].val=0;if (ll==rr) return ;int mid=(ll+rr)/2;build(ll,mid,2*n);build(mid+1,rr,2*n+1);}void updata(int ll,int rr, 阅读全文

posted @ 2011-07-12 17:19 huhuuu 阅读(191) 评论(0) 推荐(0) 编辑

摘要:统计一定区间内颜色的不同种数开个hash,在search随时记录颜色数目做完这题:对线段树有了理解更新操作时,线段树用遗传的方法,在一个区间异化时,将有用信息遗传到子代(仅仅是子代,不是所有的子孙都遗传,这样就节约了时间)统计操作时,线段树用了区间统计(不是统计每个叶子),统计未被异化的区间(不是所有子孙都统计,又节约时间了)对于函数参数的理解:当传入的是结点下标n时,函数里考虑n+n,n+n+1的子树而不仅传入有下标,还有区间时,就要分区间是在当前树的左子树,或是右子树,或是区间同时在左右子树View Code #include<stdio.h>struct data{ int 阅读全文

posted @ 2011-07-12 10:55 huhuuu 阅读(304) 评论(0) 推荐(0) 编辑

摘要:超时是因为底层结点也更新了,背离了区间更新的大原则,所以超时View Code #include<stdio.h>struct data{ int l,r,val;}st[300009];inline int max(int a,int b){ return a>b?a:b;}void build(int ll,int rr,int n)//½¨Ê÷{ st[n].l=ll; st[n].r=rr; st[n].val=1; if (ll==rr) return ; int mid=(ll+rr)/2; build(ll,mid,2*n 阅读全文

posted @ 2011-07-11 21:56 huhuuu 阅读(237) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示