zoukankan      html  css  js  c++  java
  • 题目记录

    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
    ",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
    ",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
    ",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
    ",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:
    ",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
    ",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
    ",val[u]);
     98                 else printf("invalid request!
    ");
     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
    ",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
    ",ver[rmq(mi,ma)]);
    154         }
    155     }
    156     return 0 ;
    157 }
    code
  • 相关阅读:
    伸缩布局
    布局样式
    求最小子数组01
    构建之法阅读笔记02
    第四周学习进度条
    随机生成四则运算03
    用户随机输入一组整数求出最大值
    第三周学习进度条
    随机生成四则运算表达式02
    jsp函数的使用
  • 原文地址:https://www.cnblogs.com/smile-0/p/5232783.html
Copyright © 2011-2022 走看看