第五周 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 }
Aguin

 

6.17

SuperBrother打鼹鼠

二维树状数组

 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 }
Aguin

 

6.18

P1512 SuperBrother打鼹鼠

依旧此题。昨晚就在写。刷牙的时候感觉不对。今天推了重写。

还是去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 }
Aguin

 

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 }
Aguin

 

在自家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 }
Aguin

 

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 }
Aguin

 

posted @ 2015-06-14 22:57  Aguin  阅读(198)  评论(0编辑  收藏  举报