1. cf 343 div2 

  D.Babaei and Birthday Cake

 

  求一个序列的最大上升子序列的和,比如 1 3 2 5 4 7,结果为 1 + 3 + 5 + 7 = 16;(本题要求严格递增)

  设 F[i] 为以第 i 个数结尾的子序列的最大的和,则 F[i] = max(F[j] + a[i] (1 <= j <= i && a[j] < a[i]) ) 官方题解为: 把 a 排序并记录位置 p , 并建立线段树,节点值为 F[i] , 则 , F[i] = max(A[j].val) // 1 <= j <= p[i] ;

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
#define rep(i,n) for (int i = 1 ; i <= n ; ++ i)
#define LL long long
const int maxn = 100010 ;
const double pi = acos(-1.0) ;

struct Node
{
    LL val ;
    int id ;
    friend bool operator < (const Node & P,const Node & T) {
        if (P.val == T.val) return T.id < P.id ;
        return P.val < T.val ;
    }
}a[maxn] ;

struct seg
{
    int le , ri ;
    LL sc ;
}A[maxn<<2];

int N , s[maxn] ;
LL p[maxn] ;

inline LL MAX(LL x,LL y)
{
    if (x > y) return x ;
    else return y ;
}

void build(int i,int le,int ri)
{
    A[i].le = le , A[i].ri = ri , A[i].sc = 0 ;
    if (le == ri) {
        s[le] = i ;
        return ;
    }
    int mid = (le + ri)/2 ;
    build(i<<1,le,mid) ;
    build(i<<1|1,mid+1,ri) ;
}

void update(int i,LL x)
{
    i = s[i] ;
    A[i].sc = x ;
    while (i) {
        if (A[i].sc < x) A[i].sc = x ;
        i /= 2 ;
    }
}

LL query(int i,int le,int ri)
{
    if (A[i].le == le && A[i].ri == ri) {
        return A[i].sc ;
    }
    int mid = (A[i].le + A[i].ri)/2 ;
    if (mid < le) return query(i<<1|1,le,ri) ;
    else if (ri <= mid) return query(i<<1,le,ri) ;
    else {
        return MAX(query(i<<1,le,mid),query(i<<1|1,mid+1,ri)) ;
    }
}

int main()
{
//    freopen("in.txt","r",stdin) ;
    LL r , h , x ;
    scanf("%d",&N) ;
    rep(i,N) {
        scanf("%I64d%I64d",&r,&h) ;
        a[i].id = i , a[i].val = r*r*h ;
//        printf("%I64d ",a[i].val) ;
    }
//    puts("") ;
    sort(a+1,a+1+N) ;
    rep(i,N) {
        p[a[i].id] = i ;
    }
    build(1,1,N) ;
    rep(i,N) {
        update(p[i],a[p[i]].val + query(1,1,p[i])) ;
    }
    printf("%.10f\n",1.0*(double )A[1].sc*pi) ;
    return 0 ;
}
code

 

2.cf edu round 9

 

  D.Longest Subsequence

 

  题目大意: 给你一个 N 个数的数列 ,和一个 M ,求最小公倍数 gcd <= M 的 子序列,且要求子序列的长度最长。

( 1 <= N , M <= 1e6 ; 1 <= a[i] <= 1e9)

 

  大于 M 的数可以直接去掉 , 用 cnt[x] 表示 x  出现的次数 , 枚举 gcd , 用 F[gcd] 表示最小公倍数为 gcd 时的子序列长度 , 则

 F[gcd] 为 gcd 所有的因子的个数。

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std ;
#define rep(i,n) for (int i = 1 ; i <= n ; ++ i)
#define LL long long
const int maxn = 1000010 ;

int cnt[maxn] , A[maxn] , N , M , F[maxn] ;

int main()
{

//    freopen("in.txt","r",stdin) ;
    scanf("%d%d",&N,&M) ;
    memset(cnt,0,sizeof(cnt)) ;
    memset(F,0,sizeof(F)) ;
    rep(i,N) {
        scanf("%d",&A[i]) ;
        if (A[i] <= M) cnt[A[i]] ++ ;
    }
    rep(i,M) {
        for (int j = i ; j <= M ; j += i) {
            F[j] += cnt[i] ;
        }
    }
    int id = 1 ;
    rep(i,M) {
        if (F[i] > F[id]) id = i ;
    }
    printf("%d %d\n",id,F[id]) ;
    rep(i,N) {
        if (id % A[i] == 0) printf("%d ",i) ;
    }
    puts("") ;
    return 0 ;
}
code

 

3. 树状数组 hdu 1166 敌兵布阵

  第一次写树状数组~~还不是很懂~觉得是好神奇的一种方法~看了下 这个博客,感觉讲得挺好的~~~orz......

  本题只是点更新~~用树状数组代码好短~~~

4. <LCA _tarjan> poj 1986Distance Queries

  lca 裸题~一次AC也是挺开心的&_&

  

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <cstring>
  5 #include <algorithm>
  6 using namespace std ;
  7 #define rep(i,n) for (int i = 1 ; i <= n ; ++ i)
  8 const int maxn = 100010 ;
  9 bool vis[maxn] ;
 10 int h[maxn] , hq[maxn] , s[maxn] , anc[maxn] , dis[maxn] , ans[maxn] , cnt , cntq , n , r , q ;
 11 struct Node
 12 {
 13     int nxt , w , to ;
 14 }A[maxn],Q[maxn];
 15 
 16 void Init()
 17 {
 18     memset(vis,false,sizeof(vis)) ;
 19     memset(h,-1,sizeof(h)) ;
 20     memset(hq,-1,sizeof(hq)) ;
 21     memset(ans,-1,sizeof(ans)) ;
 22     memset(dis,0,sizeof(dis)) ;
 23     rep(i,n) s[i] = anc[i] = i ;
 24     cnt = cntq = 0 ;
 25 }
 26 
 27 inline void addedge(int u,int v,int w)
 28 {
 29     A[cnt].w = w , A[cnt].to = v ;
 30     A[cnt].nxt = h[u] ;
 31     h[u] = cnt ++ ;
 32 }
 33 
 34 inline void addask(int u,int v,int id)
 35 {
 36     Q[cntq].to = v , Q[cntq].w = id ;
 37     Q[cntq].nxt = hq[u] ;
 38     hq[u] = cntq ++ ;
 39 }
 40 
 41 inline int fi(int x)
 42 {
 43     int r = x , p = x , q ;
 44     while (r != s[r]) r = s[r] ;
 45     while (p != s[p]) {
 46         q = s[p] ;
 47         s[p] = r ;
 48         p = q ;
 49     }
 50     return r ;
 51 }
 52 
 53 inline void join(int x,int y)
 54 {
 55     x = fi(x) , y = fi(y) ;
 56     if (x != y) s[x] = y ;
 57 }
 58 
 59 void tarjan(int rt)
 60 {
 61     vis[rt] = true ;
 62     int u ;
 63     anc[rt] = rt ;
 64     for (int i = h[rt] ; ~i ; i = A[i].nxt) {
 65         u = A[i].to ;
 66         if (!vis[u]) {
 67             dis[u] = dis[rt] + A[i].w ;
 68             tarjan(u) ;
 69             join(u,rt) ;
 70             anc[fi(u)] = rt ;
 71         }
 72     }
 73 
 74     for (int i = hq[rt] ; ~i ; i = Q[i].nxt) {
 75         u = Q[i].to ;
 76         if (vis[u]) {
 77             ans[Q[i].w] = dis[rt] + dis[u] - 2*dis[anc[fi(u)]] ;
 78         }
 79     }
 80 }
 81 
 82 int main()
 83 {
 84     int u , v , x ;
 85     char c ;
 86   //  freopen("in.txt","r",stdin) ;
 87     while (scanf("%d%d",&n,&r) == 2) {
 88         Init() ;
 89         rep(i,r) {
 90             scanf("%d%d%d%c%c",&u,&v,&x,&c,&c) ;
 91             addedge(u,v,x) ;
 92             addedge(v,u,x) ;
 93         //    printf("%d %d %d %c\n",u,v,x,c) ;
 94         }
 95         scanf("%d",&q) ;
 96         rep(i,q) {
 97             scanf("%d%d",&u,&v) ;
 98             addask(u,v,i) ;
 99             addask(v,u,i) ;
100         }
101         tarjan(1) ;
102         rep(i,q) printf("%d\n",ans[i]) ;
103     }
104     return 0 ;
105 }
code

 

  

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std ;
const int maxn = 50010 ;
int c[maxn] , N ;

void update(int k,int x)
{
    while (k <= N) {
        c[k] += x ;
        k += (k&(-k)) ;
    }
}

inline int Query(int i)
{
    int suma = 0 ;
    while (i) {
        suma += c[i] ;
        i -= (i&(-i)) ;
    }
    return suma ;
}

int main()
{
 //   freopen("in.txt","r",stdin) ;
    int T , kase = 1 , x , k ;
    char s[10] ;
    scanf("%d",&T) ;
    while (T --) {
        memset(c,0,sizeof(c)) ;
        scanf("%d",&N) ;
        for (int i = 1 ; i <= N ; ++ i) {
            scanf("%d",&x) ;
            update(i,x) ;
        }
        printf("Case %d:\n",kase++) ;
        while (scanf("%s",s) == 1) {
            if (s[0] == 'E') break ;
            else if (s[0] == 'A') {
                scanf("%d%d",&k,&x) ;
                update(k,x) ;
            }
            else if (s[0] == 'S') {
                scanf("%d%d",&k,&x) ;
                update(k,-x) ;
            }
            else if (s[0] == 'Q') {
                scanf("%d%d",&k,&x) ;
                printf("%d\n",Query(x)-Query(k-1)) ;
            }
        }
    }
    return 0 ;
}
clw

 5. LCA st hdu 3078Network

题意:

  给n个点Q个询问.// n <= 80000 ,Q <= 30000.

  n个数,表示第 i 个点的权值.

  一条边u , v

  k u v // 如果k == 0 , val[u] = v , 否则查找u v 路径上权值的第 k 大.

思路:完全没思路,看了别人说的~居然是先求lca,然后直接暴力,如果是一条链,每次都问 k 1 n ~~完全不知道怎么搞

ps: u == v 时特殊处理一下~

  

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <algorithm>
  5 #include <cstring>
  6 #include <cmath>
  7 #include <vector>
  8 using namespace std ;
  9 #define rep(i,n) for (int i = 1 ; i <= n ; ++ i)
 10 const int maxn = 80010 ;
 11 int n , q ;
 12 struct Node
 13 {
 14     int to , nxt ;
 15 }A[maxn<<1];
 16 int fucc[maxn] ;
 17 int h[maxn<<1] , cnt , ct , val[maxn] , fa[maxn] , ver[maxn<<1] , dep[maxn<<1] , pos[maxn] , st[maxn<<1][25] ;
 18 bool vis[maxn] ;
 19 
 20 inline void addedge(int u,int v)
 21 {
 22     A[cnt].to = v ;
 23     A[cnt].nxt = h[u] ;
 24     h[u] = cnt ++ ;
 25 }
 26 
 27 void dfs(int rt,int dis)
 28 {
 29     vis[rt] = true , ver[++ct] = rt ;
 30     pos[rt] = ct , dep[ct] = dis ;
 31     int u ;
 32     for (int i = h[rt] ; ~i ; i = A[i].nxt) {
 33         u = A[i].to ;
 34         if (!vis[u]) {
 35             fa[u] = rt ;
 36             dfs(u,dis+1) ;
 37             ver[++ct] = rt ;
 38             dep[ct] = dis ;
 39         }
 40     }
 41 }
 42 
 43 void stBuild()
 44 {
 45     rep(i,ct) st[i][0] = i ;
 46     int x , y , k ;
 47     for (int j = 1 ; (1<<j) <= ct ; ++ j) {
 48         k = (1<<j) ;
 49         for (int i = 1 ; i+k-1 <= ct ; ++ i) {
 50             x = st[i][j-1] , y = st[i+(1<<(j-1))][j-1] ;
 51             st[i][j] = dep[x] < dep[y] ? x : y ;
 52         }
 53     }
 54 }
 55 
 56 inline int rmq(int le,int ri)
 57 {
 58     if (le > ri) swap(le,ri) ;
 59     int k = (int )log2(ri-le+1.0) ;
 60     if (le+(1<<(k+1))-1 <= ri) k ++ ;
 61     int x = st[le][k] , y = st[ri-(1<<k)+1][k] ;
 62     return (dep[x] < dep[y] ? x : y) ;
 63 }
 64 
 65 void Init()
 66 {
 67     memset(h,-1,sizeof(h)) ;
 68     memset(vis,false,sizeof(vis)) ;
 69     memset(val,0,sizeof(val)) ;
 70     memset(fucc,0,sizeof(fucc)) ;
 71     ct = cnt = 0 ;
 72     fa[1] = 1 ;
 73 }
 74 
 75 int main()
 76 {
 77  //   freopen("in.txt","r",stdin) ;
 78     while (scanf("%d%d",&n,&q) == 2) {
 79         Init() ;
 80         rep(i,n) scanf("%d",&val[i]) ;
 81         int u , v , k , kk ;
 82         rep(i,n-1) {
 83             scanf("%d%d",&u,&v) ;
 84             addedge(u,v) ;
 85             addedge(v,u) ;
 86         }
 87         dfs(1,1) ;
 88         stBuild() ;
 89         while (q --) {
 90             scanf("%d%d%d",&k,&u,&v) ;
 91             if (k == 0) {
 92                 val[u] = v ;
 93                 continue ;
 94             }
 95             kk = 0 ;
 96             if (u == v) {
 97                 if(k==1)printf("%d\n",val[u]);
 98                 else printf("invalid request!\n");
 99                 continue ;
100             }
101             else {
102                 int LCA = ver[rmq(pos[u],pos[v])] ;
103                 while (v != LCA) {
104                     fucc[++kk] = val[v] ;
105                     v = fa[v] ;
106                 }
107                 while (u != LCA) {
108                     fucc[++kk] = val[u] ;
109                     u = fa[u] ;
110                 }
111                 fucc[++kk] = val[LCA] ;
112 
113                 if (k > kk) puts("invalid request!") ;
114                 else {
115                     sort(fucc+1,fucc+1+kk) ;
116                     printf("%d\n",fucc[kk-k+1]) ;
117                 }
118             }
119         }
120     }
121     return 0 ;
122 }
code

 

6.lca_st hdu 5266 pog loves szh III

题意:

题意很清楚~求好多个点(从 li 到 ri) 的 LCA , 于是想到 LCA_ST ,和模板的区别在于要用线段树或其他方式处理 li -> ri 的最值.

  1 #pragma comment(linker, "/STACK:1024000000,1024000000") 
  2 #include <iostream>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <vector>
  9 using namespace std ;
 10 #define LL long long
 11 #define rep(i,n) for (int i = 1;i <= n ; ++ i)
 12 const int maxn = 300010 ;
 13 int n , q ;
 14 struct Node
 15 {
 16     int to , nxt ;  
 17 }A[maxn<<1];
 18 int ver[maxn<<1] , dep[maxn<<1] , pos[maxn] , h[maxn] , cnt , ct ;
 19 bool vis[maxn] ;
 20 
 21 inline void addedge(int u,int v)
 22 {
 23     A[cnt].nxt = h[u] ;
 24     A[cnt].to = v ;
 25     h[u] = cnt ++ ;
 26 }
 27 
 28 void dfs(int rt,int dis)
 29 {
 30     vis[rt] = true ;
 31     ver[++ct] = rt ;
 32     pos[rt] = ct ;
 33     dep[ct] = dis ;
 34     int u ;
 35     for (int i = h[rt]; ~i ; i = A[i].nxt) {
 36         u = A[i].to ;
 37         if (!vis[u]) {
 38             dfs(u,dis+1) ;
 39             ver[++ct] = rt ;
 40             dep[ct] = dis ;
 41         }
 42     }
 43 }
 44 
 45 int st[maxn<<1][20] ;
 46 void stbuild()
 47 {
 48     rep(i,ct) st[i][0] = i ;
 49     int k , x, y ;
 50     for (int j = 1 ; (1 << j) <= ct ; ++ j) {
 51         k = 1<<j ;
 52         for (int i = 1 ; i+k-1<=ct ; ++ i) {
 53             x = st[i][j-1] , y = st[i+(1<<(j-1))][j-1] ;
 54             st[i][j] = dep[x] < dep[y] ? x : y ;
 55         }
 56     }
 57 }
 58 
 59 inline int rmq(int le,int ri)
 60 {
 61     if (le > ri) swap(le,ri) ;
 62     int k = 0;
 63     while((1<<k+1)<=ri-le+1) k++;
 64     int x = st[le][k] , y = st[ri-(1<<k)+1][k] ;
 65     return dep[x] < dep[y] ? x : y ;
 66 }
 67 
 68 struct fucc
 69 {
 70     int le , ri , ma , mi ;
 71 }D[maxn<<2];
 72 int s[maxn] ;
 73 
 74 void segbuild(int i,int le,int ri)
 75 {
 76     D[i].le = le , D[i].ri = ri ;
 77     D[i].ma = 0 , D[i].mi = (maxn<<2) ;
 78     if (le == ri) {
 79         s[le] = i ;
 80         return ;
 81     }
 82     int mid = (le+ri)/2 ;
 83     segbuild(i<<1,le,mid) ;
 84     segbuild(i<<1|1,mid+1,ri) ;
 85 }
 86 
 87 inline void update(int i,int x)
 88 {
 89     i = s[i] ;
 90     if (D[i].ma < x) D[i].ma = x ;
 91     if (D[i].mi > x) D[i].mi = x ;
 92     i /= 2 ;
 93     while (i) {
 94         D[i].ma = (D[i<<1].ma > D[i<<1|1].ma ? D[i<<1].ma : D[i<<1|1].ma) ;
 95         D[i].mi = (D[i<<1].mi < D[i<<1|1].mi ? D[i<<1].mi : D[i<<1|1].mi) ;
 96         i /= 2 ;
 97     }
 98 }
 99 
100 inline int querymin(int i,int le,int ri)
101 {
102     if (D[i].le == le && D[i].ri == ri) return D[i].mi ;
103     int mid = (D[i].le + D[i].ri)/2 ;
104     if (ri <= mid) return querymin(i<<1,le,ri) ;
105     else if (le > mid) return querymin(i<<1|1,le,ri) ;
106     else {
107         int x = querymin(i<<1,le,mid) ;
108         int y = querymin(i<<1|1,mid+1,ri) ;
109         return (x < y ? x : y) ;
110     }
111 }
112 
113 inline int querymax(int i,int le,int ri)
114 {
115     if (D[i].le == le && D[i].ri == ri) return D[i].ma ;
116     int mid = (D[i].le + D[i].ri)/2 ;
117     if (ri <= mid) return querymax(i<<1,le,ri) ;
118     else if (le > mid) return querymax(i<<1|1,le,ri) ;
119     else {
120         int x = querymax(i<<1,le,mid) ;
121         int y = querymax(i<<1|1,mid+1,ri) ;
122         return (x > y ? x : y) ;
123     }
124 }
125 
126 void Init()
127 {
128     memset(h,-1,sizeof(h)) ;
129     memset(vis,false,sizeof(vis)) ;
130     ct = cnt = 0 ;
131 }
132 
133 int main()
134 {
135  //   freopen("in.txt","r",stdin) ;
136     int u , v , ma , mi ;
137     while (scanf("%d",&n) == 1) {
138         Init() ;
139         rep(i,n-1) {
140             scanf("%d%d",&u,&v) ;
141             addedge(u,v) ;
142             addedge(v,u) ;
143         }
144         dfs(1,1) ;
145         stbuild() ;
146         segbuild(1,1,n) ;
147         rep(i,n) update(i,pos[i])  ;
148         scanf("%d",&q) ;
149         while (q --) {
150             scanf("%d%d",&u,&v) ;
151             ma = querymax(1,u,v) ;
152             mi = querymin(1,u,v) ;
153             printf("%d\n",ver[rmq(mi,ma)]);
154         }
155     }
156     return 0 ;
157 }
code