第五周 6.14-6.20
6.14-6.15
什么都没干。
6.16
好久没码题了。快结课了会空很多。但在时间上有些难以抉择。
最主要的是后面还有一系列问题要困扰我。放假家里还有事情。
烦阿烦阿 该何去何从。
因为是段增的。一开始想到了挖掘机那种方法。
但是段问的时候就挂了。
学了两颗树处理段增段问的方法。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 using namespace std; 6 # define maxn 50000+5 7 int n,c1[maxn],c2[maxn]; 8 9 int lowbit(int s) 10 { 11 return s&(-s); 12 } 13 14 void add1(int i,int x) 15 { 16 while(i<=n) {c1[i]+=x; i+=lowbit(i);} 17 return; 18 } 19 20 void add2(int i,int x) 21 { 22 while(i<=n) {c2[i]+=x; i+=lowbit(i);} 23 return; 24 } 25 26 int sum1(int i) 27 { 28 int ans=0; 29 while(i>0) {ans+=c1[i]; i-=lowbit(i);} 30 return ans; 31 } 32 33 int sum2(int i) 34 { 35 int ans=0; 36 while(i>0) {ans+=c2[i]; i-=lowbit(i);} 37 return ans; 38 } 39 40 int main(void) 41 { 42 int m; 43 while(cin>>n>>m) 44 { 45 memset(c1,0,sizeof(c1)); 46 memset(c2,0,sizeof(c2)); 47 for(int i=0;i<m;i++) 48 { 49 int k,l,r; 50 scanf("%d%d%d",&k,&l,&r); 51 if(k==1) {add1(l,1); add2(r,1);} 52 else if(k==2) printf("%d\n",sum1(r)-sum2(l-1)); 53 } 54 } 55 return 0; 56 }
6.17
二维树状数组
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 using namespace std; 5 # define maxn 1030 6 int n,c[maxn][maxn]; 7 8 int lowbit(int s) 9 { 10 return s&(-s); 11 } 12 13 void add(int x,int y,int v) 14 { 15 for(int i=x;i<=n;i+=lowbit(i)) 16 for(int j=y;j<=n;j+=lowbit(j)) 17 c[i][j]+=v; 18 return; 19 } 20 21 int sum(int x,int y) 22 { 23 int ans=0; 24 for(int i=x;i>0;i-=lowbit(i)) 25 for(int j=y;j>0;j-=lowbit(j)) 26 ans+=c[i][j]; 27 return ans; 28 } 29 30 int main(void) 31 { 32 while(cin>>n) 33 { 34 memset(c,0,sizeof(c)); 35 int m; 36 while(cin>>m) 37 { 38 if(m==1) 39 { 40 int x,y,k; 41 scanf("%d%d%d",&x,&y,&k); 42 add(x+1,y+1,k); 43 } 44 else if(m==2) 45 { 46 int x1,y1,x2,y2; 47 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 48 printf("%d\n",sum(x2+1,y2+1)-sum(x1,y2+1)-sum(x2+1,y1)+sum(x1,y1)); 49 } 50 else if(m==3) break; 51 } 52 } 53 return 0; 54 }
6.18
依旧此题。昨晚就在写。刷牙的时候感觉不对。今天推了重写。
还是去vijos交。自家oj不知怎么一直爆M阿。
二维线段树。点更新。面询问。
1 # include <iostream> 2 # include <cstdio> 3 using namespace std; 4 # define maxn 1030 5 int n; 6 7 struct nodey 8 { 9 int yl,yr,sum; 10 }; 11 12 struct nodex 13 { 14 int xl,xr; 15 nodey treey[maxn*4]; 16 17 void buildtree(int i,int l,int r) 18 { 19 treey[i].yl=l;treey[i].yr=r;treey[i].sum=0; 20 if(l<r) 21 { 22 buildtree(2*i,l,(l+r)/2); 23 buildtree(2*i+1,(l+r)/2+1,r); 24 } 25 // printf("build x:[%d,%d]y:[%d,%d]sum:%d\n",xl,xr,treey[i].yl,treey[i].yr,treey[i].sum); 26 return; 27 } 28 29 void update(int i,int y,int v) 30 { 31 treey[i].sum+=v; 32 // printf("update x:[%d,%d]y:[%d,%d]sum:%d\n",xl,xr,treey[i].yl,treey[i].yr,treey[i].sum); 33 if(treey[i].yl==treey[i].yr) return; 34 else if(y<=(treey[i].yl+treey[i].yr)/2) update(2*i,y,v); 35 else update(2*i+1,y,v); 36 return; 37 } 38 39 int query(int i,int l,int r) 40 { 41 int ans=0; 42 if(treey[i].yl>=l&&treey[i].yr<=r) return treey[i].sum; 43 if(l<=(treey[i].yl+treey[i].yr)/2) ans+=query(2*i,l,r); 44 if(r>=(treey[i].yl+treey[i].yr)/2+1) ans+=query(2*i+1,l,r); 45 return ans; 46 } 47 48 }treex[maxn*4]; 49 50 void buildtreex(int i,int l,int r) 51 { 52 treex[i].xl=l;treex[i].xr=r; 53 treex[i].buildtree(1,1,n); 54 if(l<r) 55 { 56 buildtreex(2*i,l,(l+r)/2); 57 buildtreex(2*i+1,(l+r)/2+1,r); 58 } 59 return; 60 } 61 62 void updatex(int i,int x,int y,int v) 63 { 64 treex[i].update(1,y,v); 65 if(treex[i].xl==treex[i].xr) return; 66 if(x<=(treex[i].xl+treex[i].xr)/2) updatex(2*i,x,y,v); 67 else updatex(2*i+1,x,y,v); 68 return; 69 } 70 71 int queryx(int i,int x1,int y1,int x2,int y2) 72 { 73 int ans=0; 74 if(treex[i].xl>=x1&&treex[i].xr<=x2) return treex[i].query(1,y1,y2); 75 if(x1<=(treex[i].xl+treex[i].xr)/2) ans+=queryx(2*i,x1,y1,x2,y2); 76 if(x2>=(treex[i].xl+treex[i].xr)/2+1) ans+=queryx(2*i+1,x1,y1,x2,y2); 77 return ans; 78 } 79 80 int main(void) 81 { 82 while((scanf("%d",&n))!=EOF) 83 { 84 buildtreex(1,1,n); 85 int m; 86 while(1) 87 { 88 scanf("%d",&m); 89 if(m==3) break; 90 if(m==1) 91 { 92 int x,y,k; 93 scanf("%d%d%d",&x,&y,&k); 94 updatex(1,x+1,y+1,k); 95 } 96 else if(m==2) 97 { 98 int x1,y1,x2,y2; 99 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 100 printf("%d\n",queryx(1,x1+1,y1+1,x2+1,y2+1)); 101 } 102 } 103 } 104 return 0; 105 }
update可以写成非递归形式
1 # include <iostream> 2 # include <cstdio> 3 using namespace std; 4 # define maxn 1030 5 int n,locx[maxn],locy[maxn]; 6 7 struct nodey 8 { 9 int yl,yr,sum; 10 }; 11 12 struct nodex 13 { 14 int xl,xr; 15 nodey treey[maxn*4]; 16 17 void buildtree(int i,int l,int r) 18 { 19 treey[i].yl=l;treey[i].yr=r;treey[i].sum=0; 20 if(l<r) 21 { 22 buildtree(2*i,l,(l+r)/2); 23 buildtree(2*i+1,(l+r)/2+1,r); 24 } 25 else locy[l]=i; 26 // printf("build x:[%d,%d]y:[%d,%d]sum:%d\n",xl,xr,treey[i].yl,treey[i].yr,treey[i].sum); 27 return; 28 } 29 30 int query(int i,int l,int r) 31 { 32 int ans=0; 33 if(treey[i].yl>=l&&treey[i].yr<=r) return treey[i].sum; 34 if(l<=(treey[i].yl+treey[i].yr)/2) ans+=query(2*i,l,r); 35 if(r>=(treey[i].yl+treey[i].yr)/2+1) ans+=query(2*i+1,l,r); 36 return ans; 37 } 38 39 }treex[maxn*4]; 40 41 void buildtreex(int i,int l,int r) 42 { 43 treex[i].xl=l;treex[i].xr=r; 44 treex[i].buildtree(1,1,n); 45 if(l<r) 46 { 47 buildtreex(2*i,l,(l+r)/2); 48 buildtreex(2*i+1,(l+r)/2+1,r); 49 } 50 else locx[l]=i; 51 return; 52 } 53 54 void UPDATE(int x,int y,int v) 55 { 56 for(int i=locx[x];i;i/=2) 57 for(int j=locy[y];j;j/=2) 58 treex[i].treey[j].sum+=v; 59 return; 60 } 61 62 int queryx(int i,int x1,int y1,int x2,int y2) 63 { 64 int ans=0; 65 if(treex[i].xl>=x1&&treex[i].xr<=x2) return treex[i].query(1,y1,y2); 66 if(x1<=(treex[i].xl+treex[i].xr)/2) ans+=queryx(2*i,x1,y1,x2,y2); 67 if(x2>=(treex[i].xl+treex[i].xr)/2+1) ans+=queryx(2*i+1,x1,y1,x2,y2); 68 return ans; 69 } 70 71 int main(void) 72 { 73 while((scanf("%d",&n))!=EOF) 74 { 75 buildtreex(1,1,n); 76 int m; 77 while(1) 78 { 79 scanf("%d",&m); 80 if(m==3) break; 81 if(m==1) 82 { 83 int x,y,k; 84 scanf("%d%d%d",&x,&y,&k); 85 UPDATE(x+1,y+1,k); 86 } 87 else if(m==2) 88 { 89 int x1,y1,x2,y2; 90 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 91 printf("%d\n",queryx(1,x1+1,y1+1,x2+1,y2+1)); 92 } 93 } 94 } 95 return 0; 96 }
在自家oj。树状数组好快跑完。
然而二维线段树爆M。不明所以阿。
vijos上树状数组。二维线段树。都差不多。
6.19
听了郏老大的平衡树课。然而觉得这些离我还太遥远。
作为一只小菜比。基础方面还有很大空缺。
影响最大的就是不会dp。
截取一段不知道说什么但是看起来很牛掰的网文
修炼dp。从数字三角形开始。
1 # include <iostream> 2 # include <cstdio> 3 # include <algorithm> 4 # include <cstring> 5 using namespace std; 6 int N,num[26][26],dp[26][26]; 7 8 int solve(int i,int j) 9 { 10 if(dp[i][j]>=0) return dp[i][j]; 11 return dp[i][j]=num[i][j]+( (i==N) ? 0 : max(solve(i+1,j),solve(i+1,j+1)) ); 12 } 13 14 int main(void) 15 { 16 cin>>N; 17 memset(dp,-1,sizeof(dp)); 18 for(int i=1;i<=N;i++) 19 for(int j=1;j<=i;j++) 20 scanf("%d",&num[i][j]); 21 cout<<solve(1,1)<<endl; 22 return 0; 23 }
6.20
打了个bc
hdu5273 Dylans loves sequence
比赛的时候也是发现N小 想用蠢蠢的办法 结果没有调完就结束了。
赛后看题解。思路基本上和提到的第一种做法一样。
(hack的时候也有偷看别人代码 有看到树状数组的 但大部分都是用简单方法)
赛后写完过了。然而觉得中间写的很复杂。离散化直接用了map。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <map> 5 # include <algorithm> 6 using namespace std; 7 int N,a[1005],b[1005],c[1005]; 8 9 struct node 10 { 11 int no,L,R,ans; 12 }query[100005]; 13 14 bool cmp1(node a,node b) 15 { 16 if(a.L!=b.L) return a.L<b.L; 17 else return a.R<b.R; 18 } 19 20 bool cmp2(node a,node b) 21 { 22 return a.no<b.no; 23 } 24 25 int lowbit(int s) 26 {return s&(-s);} 27 28 void add(int i,int x) 29 { 30 while(i<=N){c[i]+=x; i+=lowbit(i);} 31 return; 32 } 33 34 int sum(int i) 35 { 36 int ans=0; 37 while(i>0) {ans+=c[i];i-=lowbit(i);} 38 return ans; 39 } 40 41 int main(void) 42 { 43 int Q;cin>>N>>Q; 44 for(int i=1;i<=N;i++) scanf("%d",a+i),b[i]=a[i]; 45 sort(b+1,b+1+N); 46 map<int,int> m; 47 for(int i=1;i<=N;i++) m[b[i]]=i; 48 for(int i=1;i<=Q;i++) 49 { 50 scanf("%d%d",&query[i].L,&query[i].R); 51 query[i].no=i; query[i].ans=0; 52 } 53 sort(query+1,query+1+Q,cmp1); 54 for(int i=1;i<=Q;i++) 55 { 56 memset(c,0,sizeof(c)); 57 for(int j=query[i].L;j<=query[i].R;j++) {query[i].ans+=sum(N)-sum(m[a[j]]);add(m[a[j]],1);} 58 for(int j=i+1;j<=Q;j++) 59 { 60 if(query[j].L==query[j-1].L) 61 { 62 query[j].ans=query[j-1].ans; 63 for(int k=query[j-1].R+1;k<=query[j].R;k++) 64 { 65 query[j].ans+=sum(N)-sum(m[a[k]]); 66 add(m[a[k]],1); 67 } 68 i=j; 69 } 70 else {i=j-1;break;} 71 } 72 } 73 sort(query+1,query+1+Q,cmp2); 74 for(int i=1;i<=Q;i++) printf("%d\n",query[i].ans); 75 return 0; 76 }