北大ACM教程-二维线段树

合集下载

浙江大学 acm程序设计竞赛 培训 线段树共68页文档

浙江大学 acm程序设计竞赛 培训 线段树共68页文档
浙江大学 acm程序设计竞赛 培训 线段 树
61、辍学如磨刀之石,不见其损,日 有所亏 。 62、奇文共欣赞,疑义相与析。
63、暧暧远人村,依依墟里烟,狗吠 深巷中 ,鸡鸣 桑树颠 。 64、一生复能几,倏如流电惊。 65、少无适俗韵,性本爱丘山。
61、奢侈是舒适的,否则就不是奢侈 。——CocoCha nel 62、少而好学,如日出之阳;壮而好学 ,如日 中之光 ;志而 好学, 如炳烛 之光。 ——刘 向 63、三军可夺帅也,匹夫不可夺志也。 ——孔 丘 64、人生就是学校。在那里,与其说好 的教师 是幸福 ,不如 说好的 教师是 不幸。 ——海 贝尔 65、接受挑战,就可以享受胜利的喜悦 。——杰纳勒 尔·乔治·S·巴顿
谢谢!
ห้องสมุดไป่ตู้

线段树及其应用场景

线段树及其应用场景

线段树及其应用场景一、引言线段树(Segment Tree)是一种基于树状数组(Binary Indexed Tree)的数据结构,用于高效地处理区间查询问题。

它在许多算法和数据结构问题中都有广泛应用,如区间最值查询、区间修改和区间统计等。

二、线段树的定义和构建线段树是一种二叉树结构,每个节点代表一个区间。

叶子节点表示原始数据的单个元素,而非叶子节点则表示区间的合并结果。

线段树的构建过程可以通过递归或迭代的方式完成。

3、线段树的应用场景3.1 区间最值查询线段树的一个常见应用是区间最值查询。

给定一个数组,我们希望能够快速找到指定区间内的最大或最小值。

线段树能够在O(log n)的时间复杂度内完成单次查询,并且支持O(log n)的时间复杂度的区间修改操作。

3.2 区间修改线段树还可以用于区间修改问题。

例如,给定一个数组,我们需要对指定区间内的元素进行加法或乘法操作。

线段树可以在O(log n)的时间复杂度内完成单次修改,并且支持O(log n)的时间复杂度的区间查询操作。

3.3 区间统计线段树还可以用于区间统计问题。

例如,给定一个数组,我们需要统计指定区间内满足某种条件的元素个数。

线段树可以在O(log n)的时间复杂度内完成单次统计,并且支持O(log n)的时间复杂度的区间修改操作。

4、线段树的实现和优化4.1 线段树的存储结构线段树可以使用数组或链表来实现。

数组实现简单高效,但需要额外的空间;链表实现节省空间,但查询和修改操作的时间复杂度会增加。

4.2 线段树的查询和修改算法线段树的查询和修改算法可以通过递归或迭代的方式来实现。

递归实现简洁直观,但可能会导致函数调用过多;迭代实现效率较高,但代码复杂度较高。

4.3 线段树的优化技巧线段树的性能可以通过一些优化技巧来提升。

例如,使用延迟标记(Lazy T ag)来延迟区间修改操作的执行,减少递归或迭代次数;使用预处理技巧来提前计算一些中间结果,减少查询或修改的时间复杂度。

ACM入门题(北大oj)

ACM入门题(北大oj)

1000#include<stdio.h>int main(){int a,b,c;while(scanf("%d%d",&a,&b)!=EOF){c=a+b;printf("%d\n",c);}}1067#include<stdio.h>#include<math.h>#include<stdlib.h>int main(){int a,b;while(scanf("%d%d",&a,&b)!=EOF){if(a>b){int t=a;a=b;b=t;}int k=b-a;int a0=(int)(k*(1+sqrt(5.0))/2);if(a0==a) printf("0\n");else printf("1\n");}}1080#include<stdio.h>#include<stdlib.h>int a[5][5]={5,-1,-2,-1,-3,-1,5,-3,-2,-4,-2,-3,5,-2,-2,-1,-2,-2,5,-1,-3,-4,-2,-1,0};int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,max[105][105],b[105],d[105];char s[105],c[105];scanf("%d%s",&n,s);scanf("%d%s",&m,c);for(i=1;i<=n;i++){if(s[i-1]=='A') b[i]=0;if(s[i-1]=='C') b[i]=1;if(s[i-1]=='G') b[i]=2;if(s[i-1]=='T') b[i]=3;}for(i=1;i<=m;i++){if(c[i-1]=='A') d[i]=0;if(c[i-1]=='C') d[i]=1;if(c[i-1]=='G') d[i]=2;if(c[i-1]=='T') d[i]=3;}max[0][0]=0;for(i=1;i<=n;i++)max[i][0]=max[i-1][0]+a[b[i]][4];for(i=1;i<=m;i++)max[0][i]=max[0][i-1]+a[4][d[i]];for(i=1;i<=n;i++)for(j=1;j<=m;j++){max[i][j]=max[i-1][j-1]+a[b[i]][d[j]];if(max[i-1][j]+a[b[i]][4]>max[i][j])max[i][j]=max[i-1][j]+a[b[i]][4];if(max[i][j-1]+a[4][d[j]]>max[i][j])max[i][j]=max[i][j-1]+a[4][d[j]];}printf("%d\n",max[n][m]);}}1013#include<stdio.h>#include<algorithm>#include<math.h>#include<stdlib.h>#define PI 3.141592653using namespace std;struct point{double x;double y;}p[30005],res[30005];int cmp(point p1,point p2){return p1.y<p2.y||(p1.y==p2.y&&p1.x<p2.x);}bool ral(point p1,point p2,point p3){if((p2.x-p1.x)*(p3.y-p1.y)<=(p2.y-p1.y)*(p3.x-p1.x)) return true;return false;}double dis(point p1,point p2){return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j;for(i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);sort(p,p+n,cmp);res[0]=p[0];res[1]=p[1];int top=1;for(i=2;i<n;i++){while(top&&ral(res[top-1],res[top],p[i]))top--;res[++top]=p[i];}int len=top;res[++top]=p[n-2];for(i=n-3;i>=0;i--){while(top!=len&&ral(res[top-1],res[top],p[i]))top--;res[++top]=p[i];}double t=0;for(i=0;i<top;i++)t=t+dis(res[i],res[i+1]);printf("%.lf\n",t+2*PI*m);}}1149#include<iostream>#include<cstring>using namespace std;#define inf 0x5fffffffint a[105][105],f[1005],ct[1005],pre[205],n,m,q[105]; int bfs(){int flow=inf,qh=0,qe=1,i;memset(pre,-1,sizeof(pre));q[1]=0;pre[0]=-1;while(qh<qe){int t=q[++qh];for(i=1;i<=n+1;i++)if(pre[i]==-1&&a[t][i]>0){pre[i]=t;if(a[t][i]<flow) flow=a[t][i];if(i==n+1) return flow;q[++qe]=i;}}return -1;}void maxflow(){int res=0,ans,t;while((ans=bfs())!=-1){res=res+ans;t=n+1;while(t)a[pre[t]][t]-=ans;a[t][pre[t]]+=ans;t=pre[t];}}printf("%d\n",res);}int main(){while(scanf("%d%d",&m,&n)!=EOF){memset(f,-1,sizeof(f));memset(a,0,sizeof(a));int i,j,k,t;for(i=1;i<=m;i++)scanf("%d",&ct[i]);for(i=1;i<=n;i++){scanf("%d",&k);for(j=1;j<=k;j++){scanf("%d",&t);if(f[t]!=-1) a[f[t]][i]=inf;else a[0][i]=a[0][i]+ct[t];f[t]=i;}scanf("%d",&k);a[i][n+1]=k;}maxflow();}}1157#include<stdio.h>#include<stdlib.h>int a[105][105],b[105][105];int main(){int max(int x,int y);int n,m;while(scanf("%d%d",&n,&m)!=EOF){for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);b[1][1]=a[1][1];for(i=2;i<=m-n+1;i++){if(a[1][i]<b[1][i-1]) b[1][i]=b[1][i-1];else b[1][i]=a[1][i];}for(i=2;i<=n;i++)for(j=i;j<=i+m-n;j++){a[i][j]=a[i][j]+b[i-1][j-1];if(i==j) b[i][j]=a[i][j];else{if(a[i][j]>b[i][j-1]) b[i][j]=a[i][j];else b[i][j]=b[i][j-1];}}printf("%d\n",b[n][m]);}}1200#include<stdio.h>#include<string.h>bool flag[20000000];int a[300];char s[20000000];int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF){memset(flag,0,sizeof(flag));scanf("%s",s);int i,j=0,len=strlen(s);memset(a,0,sizeof(a));for(i=0;i<len;i++)a[s[i]]=1;for(i=0;i<256;i++)if(a[i]==1) a[i]=j++;int mod=1,res=0;for(i=0;i<n-1;i++)mod=mod*m;for(i=0;i<n;i++)res=res*m+a[s[i]];flag[res]=1;for(i=n;i<len;i++){res=res%mod*m+a[s[i]];flag[res]=1;}int count=0;mod=mod*m;for(i=0;i<=mod;i++)if(flag[i]==1) count++;printf("%d\n",count);}}1207#include<stdio.h>#include<stdlib.h>int main(){int b,c,i,j,max=0,k,t,r;while(scanf("%d%d",&b,&c)!=EOF){if(b>c){t=b;r=c;}else{t=c;r=b;}max=0;for(i=r;i<=t;i++){j=1;k=i;while(k!=1){j++;if(k%2==0) k=k/2;else k=3*k+1;}if(j>max) max=j;}printf("%d %d %d\n",b,c,max);}//system("pause");}1273#include<iostream>#include<cstring>#include<queue>using namespace std;#define inf INT_MAXint n,m,a[205][205],pre[205],lev[205],num[205]; void bfs(){queue<int>Q;memset(lev,-1,sizeof(lev));memset(num,0,sizeof(num));Q.push(n);lev[n]=0;num[0]=1;while(!Q.empty()){int t=Q.front(),i;Q.pop();for(i=1;i<=n;i++)if(lev[i]==-1&&a[i][t]>0){lev[i]=lev[t]+1;num[lev[i]]++;Q.push(i);}}}int maxflow(){int flow=0,i,ans,cur=1;bfs();while(lev[cur]<n){if(cur==n){ans=inf;while(cur!=1){if(a[pre[cur]][cur]<ans) ans=a[pre[cur]][cur];cur=pre[cur];}cur=n;while(cur!=1){a[pre[cur]][cur]-=ans;a[cur][pre[cur]]+=ans;cur=pre[cur];}flow=flow+ans;}for(i=1;i<=n;i++)if(a[cur][i]>0&&lev[cur]==lev[i]+1){pre[i]=cur;cur=i;break;}if(i>n){lev[cur]=n+1;num[lev[cur]]--;if(num[lev[cur]]==0) break;for(i=1;i<=n;i++)if(a[cur][i]>0&&lev[i]+1<lev[cur]) lev[cur]=lev[i]+1;num[lev[cur]]++;if(cur!=1) cur=pre[cur];}}return flow;}int main(){while(scanf("%d%d",&m,&n)!=EOF){int i,j;memset(a,0,sizeof(a));for(i=0;i<m;i++){int b,c,d;scanf("%d%d%d",&b,&c,&d);a[b][c]+=d;}printf("%d\n",maxflow());}}1285#include<stdio.h>#include<string.h>int num[55];unsigned __int64 f[55][55];int main(){int n,m,ct=0;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0) break;int i,j,a,k;memset(num,0,sizeof(num));for(i=0;i<n;i++){scanf("%d",&a);num[a]++;}memset(f,0,sizeof(f));f[0][0]=1;for(i=0;i<50;i++)for(j=0;j<=50;j++)for(k=0;k<=num[i+1];k++)f[i+1][j+k]=f[i+1][j+k]+f[i][j];printf("Case %d:\n",++ct);for(i=0;i<m;i++){scanf("%d",&a);printf("%I64d\n",f[50][a]);}}}1364#include <iostream>#include <queue>#include <cstring>using namespace std;int v[105],pre[105],w[105],h[105],flag[105],ct[105],d[105],n,m,num; void add(int a,int b,int c){v[num]=b;pre[num]=h[a];w[num]=c;h[a]=num++;}bool spfa(){int i;queue<int> Q;for(i=0;i<=n;i++){Q.push(i);flag[i]=1;d[i]=0;}while(!Q.empty()){int t=Q.front();Q.pop();flag[t]=0;for(i=h[t];i>=0;i=pre[i]){int p=v[i];if(d[t]+w[i]<d[p]){d[p]=d[t]+w[i];ct[p]++;if(flag[p]==0){Q.push(p);flag[p]=1;}}if(ct[p]>n) return false;}}return true;}int main(){while(cin>>n){if(n==0) break;cin>>m;int a,b,c;char s[3];num=0;memset(flag,0,sizeof(flag));memset(ct,0,sizeof(ct));memset(h,-1,sizeof(h));for(int i=1;i<=m;i++){cin>>a>>b>>s>>c;if(strcmp(s,"gt")==0) add(a-1,a+b,-1-c);else add(a+b,a-1,c-1);}if(spfa()) cout<<"lamentable kingdom"<<endl;else cout<<"successful conspiracy"<<endl;}return 0;}1384#include<stdio.h>#include<stdlib.h>int b[10005],a[600][2];int main(){int ca;scanf("%d",&ca);while(ca--){int M1,M2,M,n,i,j,value;scanf("%d%d",&M1,&M2);M=M2-M1;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d%d",&a[i][0],&a[i][1]);for(i=0;i<=M;i++)b[i]=-1;b[0]=0;for(i=0;i<n;i++)for(j=0;j+a[i][1]<=M;j++)if(b[j]!=-1){value=b[j]+a[i][0];if(value<b[j+a[i][1]]||b[j+a[i][1]]==-1)b[a[i][1]+j]=value;}if(b[M]==-1) printf("This is impossible.\n");elseprintf("The minimum amount of money in the piggy-bank is %d.\n",b[M]);}}1473#include<stdio.h>#include<math.h>#include<stdlib.h>#include<string.h>int main(){char S[300],c[300][100];int count1=0;while(scanf("%s",S)!=EOF){if(strcmp(S,"END")==0) break;int len=strlen(S),i,count=0,j=0,d;for(i=0;i<len;i++){if(S[i]!=','&&S[i]!='.'){c[count][j]=S[i];j++;}else{c[count][j]='\0';j=0;count++;}}int nw=0,ne=0,sw=0,se=0,n=0,s=0,e=0,w=0;for(i=0;i<count;i++){char cc[10];sscanf(c[i],"%[0-9]",cc);sscanf(cc,"%d",&d);if(strlen(c[i])==strlen(cc)+1){if(c[i][strlen(cc)]=='N') n+=d;if(c[i][strlen(cc)]=='S') s+=d;if(c[i][strlen(cc)]=='E') e+=d;if(c[i][strlen(cc)]=='W') w+=d;}if(strlen(c[i])==strlen(cc)+2){if(c[i][strlen(cc)]=='N'&&c[i][strlen(cc)+1]=='W')nw+=d;if(c[i][strlen(cc)]=='N'&&c[i][strlen(cc)+1]=='E') ne+=d;if(c[i][strlen(cc)]=='S'&&c[i][strlen(cc)+1]=='W') sw+=d;if(c[i][strlen(cc)]=='S'&&c[i][strlen(cc)+1]=='E') se+=d;}}double x=e-w+((ne+se-nw-sw)*sqrt(2))/2;double y=n-s+((nw+ne-sw-se)*sqrt(2))/2;double ss=sqrt(x*x+y*y);count1++;printf("Map #%d\n",count1);printf("The treasure is located at (%.3lf,%.3lf).\n",x,y);printf("The distance to the treasure is %.3lf.\n",ss);printf("\n");}}1505#include<stdio.h>#include<string.h>#include<stdlib.h>int a[510],s[510],t[505][505],num[505],flag[505];int ma(int x,int y){if(x<y) return y;return x;}int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,k,res;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&a[i]);s[0]=0;for(i=1;i<=n;i++)s[i]=s[i-1]+a[i];for(i=1;i<n;i++)t[1][i]=s[i];memset(flag,0,sizeof(flag));for(i=2;i<m;i++)for(j=i;j<n;j++){res=1000000000;for(k=i-1;k<=j-1;k++)if(res>ma(t[i-1][k],s[j]-s[k])) res=ma(t[i-1][k],s[j]-s[k]);t[i][j]=res;}res=s[n];for(i=m-1;i<n;i++)if(ma(t[m-1][i],s[n]-s[i])<res) res=ma(t[m-1][i],s[n]-s[i]);num[0]=n;for(i=1;i<m;i++){int ti=0;for(j=num[i-1];j>m-i;j--){ti=ti+a[j];if(ti>res) break;}num[i]=j;flag[j]=1;}for(i=1;i<n;i++){if(flag[i]==0) printf("%d ",a[i]);else printf("%d / ",a[i]);}printf("%d\n",a[i]);}}1511#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define inf 2000000000using namespace std;int ct,pre[1000005],len[1000005],v[1000005],h[1000005],n,m,vis[1000005],l[1000005]; int a[1000005],b[1000005],c[1000005];queue<int> Q;void add(int a,int b,int c){pre[ct]=h[a];len[ct]=c;v[ct]=b;h[a]=ct++;}void spfa(){int i;memset(vis,0,sizeof(vis));Q.push(1);vis[1]=1;for(i=1;i<=n;i++)l[i]=inf;l[1]=0;while(!Q.empty()){int t=Q.front();for(i=h[t];i!=-1;i=pre[i])if(l[t]+len[i]<l[v[i]]){l[v[i]]=l[t]+len[i];if(vis[v[i]]==0){vis[v[i]]=1;Q.push(v[i]);}}Q.pop();vis[t]=0;}}int main(){int ca;scanf("%d",&ca);while(ca--){scanf("%d%d",&n,&m);int i,j;__int64 res=0;ct=0;memset(h,-1,sizeof(h));for(i=0;i<m;i++){scanf("%d%d%d",&a[i],&b[i],&c[i]);add(a[i],b[i],c[i]);}spfa();for(i=2;i<=n;i++)res=res+l[i];ct=0;memset(h,-1,sizeof(h));for(i=0;i<m;i++)add(b[i],a[i],c[i]);spfa();for(i=2;i<=n;i++)res=res+l[i];printf("%I64d\n",res);}}1609#include<stdio.h>#include<stdlib.h>int a[105][105];int main(){int n;while(scanf("%d",&n)!=EOF){if(n==0){printf("*\n");break;}int i,j;for(i=0;i<101;i++)for(j=0;j<101;j++)a[i][j]=0;for(i=0;i<n;i++){int m,k;scanf("%d%d",&m,&k);a[m][k]=a[m][k]+1;}for(i=1;i<101;i++)for(j=1;j<101;j++)if(i*j!=1){if(a[i][j-1]>=a[i-1][j])a[i][j]=a[i][j]+a[i][j-1];elsea[i][j]=a[i][j]+a[i-1][j];}printf("%d\n",a[100][100]);}}1611#include<iostream>using namespace std;int f[30005],cont[30005];int findf(int a){if(f[a]!=a) f[a]=findf(f[a]);return f[a];}void com(int a,int b){int x=findf(a);int y=findf(b);if(x==y) return;if(cont[x]<=cont[y]){f[x]=y;cont[y]=cont[x]+cont[y];}else{f[y]=x;cont[x]=cont[x]+cont[y];}}int main(){int m,n;while(scanf("%d%d",&n,&m)!=EOF&&n){int num,st,i,j,ed;for(i=0;i<n;i++){f[i]=i;cont[i]=1;}for(i=0;i<m;i++){scanf("%d%d",&num,&st);for(j=1;j<num;j++){scanf("%d",&ed);com(st,ed);}}printf("%d\n",cont[findf(0)]);}}1651#include<stdio.h>#include<stdlib.h>long a[105],i,s[105][105],j,t,k;int main(){int n;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%ld",&a[i]);for(i=0;i<n-1;i++)s[i][i+1]=0;for(j=2;j<n;j++)for(i=0;i+j<n;i++){t=100000000;for(k=i+1;k<i+j;k++)if(s[i][k]+s[k][i+j]+a[i]*a[k]*a[i+j]<t)t=s[i][k]+s[k][i+j]+a[i]*a[k]*a[i+j];s[i][i+j]=t;}printf("%ld\n",s[0][n-1]);}}1753#include<iostream>using namespace std;int t[]={19,39,78,140,305,626,1252,2248,4880,10016,20032,35968,12544,29184,58368,51200}; #define SIZE 65535int BFS(int state){int visited[SIZE],d[SIZE],u,v,i;int Qu[SIZE],rear,front;memset(visited,0,sizeof(visited));visited[state]=1;d[state]=0;rear=front=0;Qu[++rear]=state;while(rear!=front){u=Qu[++front];for(i=0;i<16;++i) {v=u^t[i];if(v==0 || v==65535) return d[u]+1;if(visited[v]==0){visited[v]=1;d[v]=d[u]+1;Qu[++rear]=v;}visited[u]=-1;}return -1;}int main(){char ch[5][5];int i,j,start;start=0;for(i=0;i<4;++i)scanf("%s",ch[i]);for(i=0;i<4;++i)for(j=0;j<4;++j)if(ch[i][j]=='b') start^=(1<<((3-i)*4+(3-j)));if(start==0||start==65535) printf("0\n");else{int result=BFS(start);if(result==-1) printf("Impossible\n");else printf("%d\n",result);}}1797#include<stdio.h>#include<string.h>int a[1005][1005],vis[1005],len[1005];int mm(int a,int b){return a<b?a:b;}int main(){int ca,ct=0;scanf("%d",&ca);while(ca--){int n,m;scanf("%d%d",&n,&m);int i,j;memset(a,0,sizeof(a));for(i=1;i<=m;i++)int r,t,l;scanf("%d%d%d",&r,&t,&l);a[r][t]=l;a[t][r]=l;}memset(vis,0,sizeof(vis));for(i=2;i<=n;i++)len[i]=a[1][i];vis[1]=1;for(i=1;i<n;i++){int mmax=0,k;for(j=2;j<=n;j++)if(vis[j]==0&&len[j]>mmax){mmax=len[j];k=j;}vis[k]=1;if(k==n) break;for(j=2;j<=n;j++)if(vis[j]==0){int length=mm(len[k],a[k][j]);if(length>len[j]) len[j]=length;}}printf("Scenario #%d:\n%d\n\n",++ct,len[n]);}}1845#include<iostream>#include<cstring>using namespace std;#define mod 9901__int64 pri[7505],a[100],num[100];void prime(){memset(pri,0,sizeof(pri));int i,j;for(i=2;i<=90;i++)for(j=2;i*j<=7500;j++)j=0;for(i=2;i<=7500;i++)if(pri[i]==0) pri[j++]=i;}__int64 yu(__int64 a,__int64 b){__int64 res=1,c=mod;while(b){if(b%2==0){a=(a%c)*(a%c)%c;b=b/2;}else{res=res*a%c;b--;}}return res;}__int64 f(__int64 a,__int64 b){if(b==0) return 1;if(b==1) return (1+a)%mod;if(b%2==0) return (yu(a,b/2)+(1+yu(a,b/2+1))*f(a,b/2-1))%mod;return ((1+yu(a,b/2+1))*f(a,b/2))%mod;}int main(){prime();int n,m;while(scanf("%d%d",&n,&m)!=EOF){int i,j=0;if(n==0){printf("1\n");continue;}for(i=0;pri[i]*pri[i]<=n;i++)if(n%pri[i]==0){int t=0;while(n%pri[i]==0){t++;n=n/pri[i];}a[j]=pri[i];num[j++]=t;}if(n!=1){a[j]=n;num[j++]=1;}__int64 res=1;for(i=0;i<j;i++)res=res*f(a[i],num[i]*m)%mod;printf("%I64d\n",res);}}1941#include<stdio.h>#include<string.h>int h[22],s[22];char c[1025][2050],ss[1025][2050];void solve(int m){int i,j;if(m==1){h[m]=4;s[m]=2;c[1][1]=' ';c[1][4]=' ';c[1][2]='/';c[1][3]='\\';c[2][1]='/';c[2][2]='_';c[2][3]='_';c[2][4]='\\';memcpy(ss,c,sizeof(c));}if(m!=1){memset(c,' ',sizeof(c));solve(m-1);h[m]=h[m-1]*2;s[m]=s[m-1]*2;for(i=s[m-1]+1;i<=s[m];i++)for(j=1;j<=h[m-1];j++)c[i][j]=c[i][j+h[m-1]]=ss[i-s[m-1]][j];for(i=1;i<=s[m-1];i++)for(j=h[m-1]/2*3;j>h[m-1]/2;j--){c[i][j]=ss[i][j-h[m-1]/2];c[i][j-h[m-1]/2]=' ';}memcpy(ss,c,sizeof(c));}}int main(){int n,i,j,k;h[0]=2;solve(10);while(scanf("%d",&n)!=EOF&&n){for(i=1;i<=s[n];i++){for(j=h[9]-h[n]/2+1;j<=h[9]+i;j++)printf("%c",c[i][j]);printf("\n");}printf("\n");}}1947#include<iostream>#include<algorithm>using namespace std;#define big 10000000int num[155],flag[155],son[155][155],step[155][155],n,m,root; void dsf(int v)int i,j,k;if(v!=root) step[v][1]=num[v]+1;else step[v][1]=num[v];for(i=0;i<num[v];i++){dsf(son[v][i]);for(j=m-1;j>=1;j--)if(step[v][j]<big){for(k=1;k+j<=m;k++)step[v][k+j]=min(step[v][k+j],step[v][j]+step[son[v][i]][k]-2);}}}int main(){while(scanf("%d%d",&n,&m)!=EOF){memset(num,0,sizeof(num));memset(flag,0,sizeof(flag));int i,a,b,j;for(i=1;i<n;i++){scanf("%d%d",&a,&b);flag[b]=1;son[a][num[a]++]=b;}for(i=1;i<=150;i++)for(j=1;j<=150;j++)step[i][j]=big;for(i=1;i<=n;i++)if(flag[i]==0){root=i;dsf(i);break;}int res=big;for(i=1;i<=n;i++)if(step[i][m]<res) res=step[i][m];printf("%d\n",res);}}1964#include<stdio.h>#include<string.h>char s[1005][1005][2];int a[1005][1005],pre[1005],next[1005];int main(){int ca;scanf("%d",&ca);while(ca--){int n,m,i,j,k,res=0;scanf("%d%d",&n,&m);for(i=0;i<n;i++)for(j=0;j<m;j++)scanf("%s",s[i][j]);for(i=0;i<m;i++)if(strcmp(s[0][i],"F")==0) a[0][i]=1;else a[0][i]=0;for(i=1;i<n;i++)for(j=0;j<m;j++)if(strcmp(s[i][j],"F")==0) a[i][j]=a[i-1][j]+1;else a[i][j]=0;for(i=0;i<n;i++){memset(pre,-1,sizeof(pre));for(j=1;j<m;j++)for(k=j-1;k!=-1;k=pre[k])if(a[i][k]<a[i][j]){pre[j]=k;break;}for(j=0;j<m;j++)next[j]=m;for(j=m-2;j>=0;j--)for(k=j+1;k!=m;k=next[k])if(a[i][k]<a[i][j]){next[j]=k;break;}for(j=0;j<m;j++)if((next[j]-pre[j]-1)*a[i][j]>res) res=(next[j]-pre[j]-1)*a[i][j];}printf("%d\n",res*3);}}。

ACM必要的算法合集---队员常备

ACM必要的算法合集---队员常备
2. 最短路,次短路,K 短路 spfa dijkstra floyd
3. 图的连通 连通分量 割点,割边
4. 网络流 最大流 最小割 费用流 分数规划
5. 树相关 树上倍增,公共祖先 树链剖分 树的分治算法(点分治,边分治,*动态?树
分治) 动态树 (LCT,*树分块) 虚树 *prufer 编码
记忆化搜索 斯坦纳树 背包九讲 2. 斜率优化与* 四边形不等式优化 3. 环 + 外向树上的动态规划 4. *插头动态规划
1.9 计算几何
1. 计算几何基础 2. 三维计算几何初步 3. *梯形剖分与*三角形剖分 4. 旋转卡壳 5. 半平面交 6. pick 定理 7. 扫描线
1.10 搜索相关
9. *拉格朗日乘子法 10. 中国剩余定理 11. 线性规划与网络流 12. 单纯型线性规划 13. 辛普森积分 14. 模线性方程组 15. 容斥原理与莫比乌斯反演 16. 置换群 17. 快速傅里叶变换 18. *大步小步法(BSGS),扩展 BSGS
1.8 动态规划
1. 一般,背包,状压,区间,环形,树形,数 位动态规划
1. bfs,dfs 2. A* 算法 3. 迭代加深搜索,双向广搜
1.11 特殊算法
1. 莫队算法,*树上莫队 2. 模拟退火 3. 爬山算法 4. 随机增量法
1.12 其它重要工具与方法
1.模拟与贪心 2. 二分,三分法(求偏导) 3. 分治,CDQ 分治 4. 高精度 5. 离线 6. ST 表
1.13 STL
1. map 2. priority_queue 3. set 4. bitset 5. rope
1.14 非常见算法
1. *朱刘算法 2. *弦图与区间图

线段树的概念与应用

线段树的概念与应用

线段树的概念与应用线段树(Segment Tree)是一种用于解决区间查询问题的数据结构。

它可以高效地支持以下两种操作:区间修改和区间查询。

线段树的应用非常广泛,在离线查询、区间统计、区间更新等问题中有着重要的作用。

一、概念线段树是一颗二叉树,其中每个节点代表了一个区间。

根节点表示整个待查询区间,而叶子节点表示的是单个元素。

每个内部节点包含了其子节点所代表区间的并集。

二、构建线段树线段树的构建过程是自底向上的。

将待查询数组划分成一颗满二叉树,并将每个区间的和存储在相应的节点中。

对于叶子节点,直接存储对应元素的值。

而非叶子节点的值可以通过其子节点的值计算得到。

三、线段树的查询对于区间查询操作,可以通过递归方式实现。

从根节点开始,判断查询区间和当前节点所代表的区间是否有交集。

若没有交集,则返回当前节点的默认值。

若查询区间包含当前节点所代表的区间,则返回当前节点存储的值。

否则,将查询区间分割成左右两部分继续递归查询。

四、线段树的更新对于区间更新操作,也可以通过递归方式实现。

与查询操作类似,首先判断查询区间和当前节点所代表的区间的关系。

若没有交集,则无需更新。

若查询区间包含当前节点所代表的区间,则直接更新当前节点的值。

否则,将更新操作分割成左右两部分继续递归更新。

五、应用案例:区间最值查询一个常见的线段树应用是求解某个区间的最值。

以查询区间最小值为例,可以通过线段树来高效地解决。

首先构建线段树,然后进行区间查询时,分为以下几种情况处理:若当前节点所代表的区间完全包含于查询区间,则直接返回该节点的值;若当前节点所代表的区间与查询区间没有交集,则返回默认值;否则,将查询区间分割成左右两部分继续递归查询,最后返回两个子区间查询结果的较小值。

六、总结线段树是一种非常有用的数据结构,能够高效地解决区间查询问题。

通过合理的构建和操作,线段树可以应用于多种场景,如区间最值查询、离线查询等。

熟练掌握线段树的概念和应用方法,对解决问题具有重要意义。

浙江大学_acm程序设计竞赛_培训_线段树68页PPT

浙江大学_acm程序设计竞赛_培训_线段树68页PPT
Thank you

29、在一切能够接受法律支配的人类 的状态 中,哪 里没有 法律, 那里就 没有自 由。— —洛克

30、风俗可以造就法律,也可以废除 法律。 ——塞·约翰逊
线段树
6、最大的骄傲于最大的自卑都表示心灵的最软弱无力。——斯宾诺莎 7、自知之明是最难得的知识。——西班牙 8、勇气通往天堂,怯懦通往地狱。——塞内加 9、有时候读书是一种巧妙地避开思考的方法。——赫尔普斯 10、阅读一切好书如同和过去最杰出的人谈话。——笛卡儿
浙江大学_acm程序设计竞赛_培训_


26、我们像鹰一样,生来就是自由的 ,但是 为了生 存,我 们不得 不为自 己编织 一个笼 子,然 后把自 己关在 里面。 ——博 莱索

27、法律如果不讲道理,即使延续时 间再长 ,也还 是没有 制约力 的。— —爱·科 克

28、好法律是由坏风俗创造出来的。 ——马 克罗维 乌斯

ACM训练计划建议(转)

ACM训练计划建议(转)

ACM训练计划建议(转)前⾔:⽼师要我们整理⼀份训练计划给下⼀届的学弟学妹们,整理出来了,费了不少笔墨,就也将它放到博客园上供⼤家参考。

菜鸟之作,⼤⽜勿喷,如有不当或补充之处,欢迎指出。

本建议书分为三个阶段,⼤⼀、⼤⼆、⼤三。

⼤四暂没整理,⼀⽅⾯是⼤四要⾯临考验和找⼯作的问题,坚持继续acm的很少,另⼀⽅⾯,本⼈还没⼤四……下⾯以个⼈经验分析⼀下这三个阶段建议学习的内容和具体的训练计划。

正⽂:⼤⼀(第⼀阶段): ⼤⼀是时间最充裕的⼀段时间,也是可塑性最⾼的⼀个阶段。

⼤⼀你有很多⾃由时间可以⾃⼰分配,建议这段时间先打好c/c++基础,或者是任何⼀门语⾔的基础,尽量做到“半精通”。

因为像c++这种语⾔,⼏年内达到精通都是不可能的。

⽽我这⾥所说的“半精通”,实际上是将课本完全搞透的基础上,再在课外拓展⼀些内容,加深对语⾔本⾝的理解。

为什么我这⾥强调语⾔的重要性呢?⼀⽅⾯是为了以后搞acm的需要,语⾔通畅了,可以保证你实现⼤部分算法没有障碍,⽽⽐赛时,时间是很重要的。

另⼀⽅⾯,也是你⾝为学计算机的学⽣的⼀个必须要学习的能⼒,语⾔就是你⼿中的剑,以后能披荆斩棘⾛多远,剑有多锋利占很⼤因素。

另⼀⽅⾯,建议打好数学的基础。

学长⾝为过来⼈,深受数学烂的苦。

acm越到后期的时候,其实⽤到的数学知识就越多。

像有些题⽬,⾚裸裸的就是求积分,还有⼀些题⽬,将求期望嵌⼊到了DP的题⽬⾥…… 其实这些还好说,都是显式的题⽬,还有⼀种隐式的东西,对acm帮助最⼤,那就是数学思维。

有数学思维和没有数学思维的区别,就是⼀道题有N种思路和N*N种思路的区别。

这越到后期越明显,思路很重要,⽐赛时⾯对⼀道题团队⾥⾸先要有多种思路可供分析,然后⼤家讨论哪种思路是最可⾏的,确定之后就是最擅长这个思路的⼈实现算法。

如果分析⼀道题⽬的时候,产⽣的思路很少,那么⽆疑会降低这道题的AC命中率。

啰嗦了这么多,其实我就想给⼤⼀的新⽣们强调两点,语⾔和数学。

zufe_acm学习计划

zufe_acm学习计划

第一阶段初级:第1周-第2周(共80题)项目时间必做题目基本算法枚举第1周poj1753,poj2965贪心poj1328,poj2109,poj2586分治法递推构造法poj3295模拟法poj1068,poj2632,poj1573,poj2993,poj2996图算法图的深度优先遍历和广度优先遍历第1周最短路径算法poj1860,poj3259,poj1062,poj2253,poj1125,poj2240最小生成树算法poj1789,poj2485,poj1258,poj3026拓扑排序poj1094二分图的最大匹配poj3041,poj3020最大流的增广路算法poj1459,poj3436数据结构串第1周poj1035,poj3080,poj1936排序poj2388,poj2299简单并查集的应用哈希表和二分查找等高效查找法poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503哈夫曼树poj3253堆树poj2513简深度优先搜索第2周poj2488,poj3083,poj3009,单搜索poj1321,poj2251广度优先搜索poj3278,poj1426,poj3126,poj3087.poj3414简单搜索技巧和剪枝poj2531,poj1416,poj2676,poj1129动态规划背包问题第2周poj1837,poj1276型如下表的简单DP poj3267,poj1836,poj1260,poj2533,poj3176,poj1080,poj1159数学组合数学第2周POJ3252,poj1850,poj1019,poj1942数论poj2635,poj3292,poj1845,poj2115计算方法poj3273,poj3258,poj1905,poj3122计算几何学几何公式第2周叉积和点积的运用poj2031,poj1039多边型的简单算法和相关判定poj1408,poj1584凸包poj2187,poj1113第二阶段中级:第3周-第4周(共85题)项目时间必做题目基本算法C++的标准模版库的应用第3周poj3096,poj3007较为复杂的模拟题的训练poj3393,poj1472,poj3371,poj1027,poj2706图算差分约束系统的建立和求解第3周poj1201,poj2983法最小费用最大流poj2516,poj2516,poj2195双连通分量poj2942强连通分支及其缩点poj2186图的割边和割点poj3352最小割模型poj3308数据结构线段树第3周poj2528,poj2828,poj2777,poj2886,poj2750静态二叉检索树poj2482,poj2352树状树组poj1195,poj3321RMQ poj3264,poj3368并查集的高级应用poj1703,2492KMP算法poj1961,poj2406搜索最优化剪枝和可行性剪枝第3周搜索的技巧和优化poj3411,poj1724记忆化搜索poj3373,poj1691动态规划较为复杂的动态规划第4周poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034记录状态的动态规划poj3254,poj2411,poj1185树型动态规划poj2057,poj1947,poj2486,poj3140数学组合数学第4周poj1286,poj2409,poj3270,poj1026高斯消元法poj2947,poj1487,poj2065,poj1166,poj1222概率问题poj3071,poj3440GCD、扩展的欧几里德poj3101计算方法poj2976,poj3150,poj3422,poj3070, poj3301随机化算法poj3318,poj2454杂题poj1870,poj3296,poj3286,poj1095计算几何学坐标离散化第4周扫描线算法poj1765,poj1177,poj1151,poj3277,poj2280,poj3004边形的内核poj3130,poj3335几何工具的综合应用poj1819,poj1066,poj2043,poj3227,poj2165,poj3429第三阶段高级:第5周-第6周(共59题)项目时间必做题目基本算法代码快速写成第5周poj2525,poj1684,poj1421,poj1048,poj2050,poj3306保证正确性和高效性poj3434图算法度限制最小生成树和第K最短路第5周poj1639最短路,最小生成树,二分图,最大流问题的相关理论poj3155,poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446最优比率生成树poj2728最小树形图poj3164次小生成树无向图、有向图的最小环数据结trie图的建立和应用第5周poj2778 LCA和RMQ问题poj1330双端队列和它的应用poj2823构左偏树后缀树poj3415,poj3294搜索较麻烦的搜索题目训练第5周poj1069,poj3322,poj1475,poj1924,poj2049,poj3426广搜的状态优化poj1768,poj1184,poj1872,poj1324,poj2046,poj1482深搜的优化poj3131,poj2870,poj2286动态规划需要用数据结构优化的动态规划第6周poj2754,poj3378,poj3017四边形不等式理论较难的状态DP poj3133数学组合数学第6周poj2888,poj2154博奕论poj3317,poj1085计算几何学半平面求交第6周poj3384,poj2540可视图的建立poj2966点集最小圆覆盖对踵点poj2079综合题第6周poj3109,poj高手给的训练计划一般要做到50行以内的程序不用调试、100行以内的二分钟内调试成功.acm主要是考算法的,主要时间是花在思考算法上,不是花在写程序与debug上。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

二维线段树
可以用树套树方式实现,即每个外层线 段树的节点对应于一棵内层线段树。如 果外层线段树根对应的区间是x方向的 [1,n],那么内层线段树根节点对应的区间 是y方向的[1,m],那么整个线段树可以存 在一个n行m列的二维数组里。
也可以用一个外层线段树节点里存一棵内层 线段树的方式来实现。
二维线段树
ቤተ መጻሕፍቲ ባይዱ所有性质与线段树类似,插入、删除、查找 等时间复杂度为O(logn*logm)。
POJ 2155 Matrix N * N 的矩阵,每个元素要么是0,要么是1,开 始全0 不断进行两种操作: 1) C x1 y1 x2 y2 表示要将左上角为(x1,y1),右下 角为(x2,y2)的子矩阵里的全部元素都取反(0 变1,1变0) (1<=x1<=x2<=n,1<=y1<=y2<=n) 2) Q x y 查询(x,y)处元素的值
POJ 2155 Matrix 如果用二维树状数组,那么每次C操作(子矩阵取 反)的时间是O(n*n),太慢 所以要用二维线段树 X方向对应于外层线段树的节点,Y方向对应于内 层线段树的节点。每一个外层线段树的节点,都 对应一棵内层的线段树,所以空间复杂度是 O(n*n) 执行 C x1 y1 x2 y2 时先根据[x1,x2]访问一系列 被该区间覆盖的外层树节点,然后在被完整覆盖 的外层节点中,根据[y1,y2]再去访问内层线段树 。
相关文档
最新文档