• 线段树


    感觉线段树......有点捉急啊........

    hdu1166    敌兵布阵

    很基础的题目~,就只有建树~更新点~和询问~。。。。。。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int MAX=55555;
     7 int a[MAX<<2];
     8 
     9 void build(int l,int r,int x)         //建树
    10 {
    11     if(l==r)
    12     {
    13         scanf("%d",&a[x]);
    14         return;
    15     }
    16     int m=(l+r)>>1;
    17     build(l,m,x<<1);
    18     build(m+1,r,x<<1|1);
    19     a[x]=a[x<<1]+a[x<<1|1];
    20 }
    21 
    22 void update(int k,int word,int l,int r,int x)       //更新数据
    23 { 
    24     if(l==r)
    25     {
    26         a[x]+=word;
    27         return;
    28     }
    29     int m=(l+r)>>1;
    30     if(k<=m) update(k,word,l,m,x<<1);
    31     else
    32         update(k,word,m+1,r,x<<1|1);
    33     a[x]=a[x<<1]+a[x<<1|1];
    34 }
    35 
    36 int query(int le,int ri,int l,int r,int x)       //询问
    37 {
    38     if(le<=l && ri>=r)
    39         return a[x];
    40     int m=(l+r)>>1,re=0;
    41     if(le<=m) re+=query(le,ri,l,m,x<<1);
    42     if(ri>m) re+=query(le,ri,m+1,r,x<<1|1);
    43     return re;
    44 }
    45 
    46 int main()
    47 {
    48     int t,n,cas=0;
    49     char str[10];
    50     scanf("%d",&t);
    51     while(t--)
    52     {
    53         printf("Case %d:
    ",++cas);
    54         scanf("%d",&n);
    55         build(1,n,1);
    56         while(~scanf("%s",str))
    57         {
    58             if(str[0]=='E') break;
    59             int a,b;
    60             scanf("%d%d",&a,&b);
    61             if(str[0]=='Q') printf("%d
    ",query(a,b,1,n,1));
    62             else
    63                 if(str[0]=='S') update(a,-b,1,n,1);
    64             else
    65                 update(a,b,1,n,1);
    66         }
    67     }
    68     return 0;
    69 }

    //memory:748KB time:218ms

    hdu1754     I Hate It

    代码:

    感觉这道题和前面的那道很相似~~~ 

      1 #include <iostream>
      2 #include <cstdio>
      3 using namespace std;
      4 
      5 #define MAX_N 200000
      6 int big;
      7 
      8 class Node
      9 {
     10 public:
     11     int left,right,data, maxx;
     12 }stu[MAX_N*4];
     13 
     14 int Max(int a,int b)
     15 {
     16     return a>b?a:b;
     17 }
     18 
     19 void CreateTree(int i,int a,int b)
     20 {
     21     stu[i].left = a;
     22     stu[i].right = b;
     23     stu[i].maxx = 0;
     24     stu[i].data = 0;
     25     if(a == b)
     26         return;
     27     else
     28     {
     29         int mid = (a+b)/2;
     30         CreateTree(i*2,a,mid);
     31         CreateTree(i*2+1,mid+1,b);
     32     }
     33 }
     34 
     35 void updata(int i,int a,int b)
     36 {
     37     if(stu[i].left==a && stu[i].right==a)
     38     {
     39         stu[i].data = b;
     40         stu[i].maxx = b;
     41     }
     42     else
     43     {
     44         int mid=(stu[i].left+stu[i].right)/2;
     45         if(a<=mid)
     46             updata(i*2,a,b);
     47         else
     48             updata(i*2+1,a,b);
     49         if(b>stu[i].maxx)
     50             stu[i].maxx=b;
     51     }
     52 }
     53 
     54 void find(int i,int a,int b)
     55 {
     56     if(stu[i].left == a && stu[i].right == b)
     57     {
     58         if(stu[i].maxx > big)
     59             big = stu[i].maxx;
     60     }
     61     else
     62     {
     63         int mid = (stu[i].left + stu[i].right)/2;
     64         if(b <= mid)
     65         {
     66             find(i*2,a,b);
     67         }
     68         else if(a > mid)
     69         {
     70             find(i*2+1,a,b);
     71         }
     72         else
     73         {
     74             find(i*2,a,mid);
     75             find(i*2+1,mid+1,b);
     76         }
     77     }
     78 }
     79 
     80 int main()
     81 {
     82     int n,m,num;
     83     int i;
     84 
     85     while(scanf("%d%d",&n,&m)!=EOF)
     86     {
     87         CreateTree(1,1,n);
     88         for(i=1;i<=n;i++)
     89         {
     90             scanf("%d",&num);
     91             updata(1,i,num);
     92         }
     93         char c;
     94         int x1,x2;
     95         while(m--)
     96         {
     97             scanf("%*c%c",&c);
     98             scanf("%d%d",&x1,&x2);
     99             if(c == 'Q')
    100             {
    101                 big = 0x80000000;
    102                 find(1,x1,x2);
    103                 printf("%d
    ",big);
    104             }
    105             else
    106                 updata(1,x1,x2);
    107         }
    108     }
    109     return 0;
    110 }
    View Code

     //memory:8452KB time:1093ms

    尼玛........用a>b?a:b;居然超时.......直接用max()函数就木有超时........T T

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int MAX=222222;
     7 int a[MAX<<2];
     8 
     9 void build(int l,int r,int x)
    10 {
    11     if(l==r)
    12     {
    13         scanf("%d",&a[x]);
    14         return;
    15     }
    16     int m=(l+r)>>1;
    17     build(l,m,x<<1);
    18     build(m+1,r,x<<1|1);
    19     a[x]=max(a[x<<1],a[x<<1|1]);
    20 }
    21 
    22 void update(int p,int w,int l,int r,int x)
    23 {
    24     if(l==r)
    25     {
    26         a[x]=w;
    27         return;
    28     }
    29     int m=(l+r)>>1;
    30     if(p<=m) update(p,w,l,m,x<<1);
    31     if(p>m) update(p,w,m+1,r,x<<1|1);
    32     a[x]=max(a[x<<1],a[x<<1|1]);
    33 }
    34 
    35 int query(int le,int ri,int l,int r,int x)
    36 {
    37     if (le<=l && r<=ri)
    38         return a[x];
    39     int m = (l + r) >> 1;
    40     int re=0;
    41     if(le<=m) re=max(re,query(le,ri,l,m,x<<1));
    42     if(ri>m) re=max(re,query(le,ri,m+1,r,x<<1|1));
    43     return re;
    44 }
    45 
    46 int main()
    47 {
    48     int m,n;
    49     char str[2];
    50     while(~scanf("%d%d",&m,&n))
    51     {
    52         build(1,m,1);
    53         while(n--)
    54         {
    55             int a,b;
    56             scanf("%s",str);
    57             scanf("%d%d",&a,&b);
    58             if(str[0]=='Q') printf("%d
    ",query(a,b,1,m,1));
    59             else
    60                 update(a,b,1,m,1);
    61         }
    62     }
    63     return 0;
    64 }

    //memory:2284KB  time:500ms

    hdu1394   Minimum Inversion Number

    题意:就是给出一串有序数列,你可以将数列(a0,a1,...,an)的首个数字(a0)移到数列最后面~可以移动n次,问在这些数列中最小的inversion number是多少~

    PS:inversion number是——如ai与aj,其中i<j但ai>aj。

    【注】题中可以知道:当求出了最初数列的inversion number数(sum),那么当把a[i]移动到队尾时,此时的inversion number为sum=sum+n-1+a[i]+a[i]。(这个结论很容易得出的~~~)

    方法一:暴力求解~

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 int a[10050];
     7 
     8 int main()
     9 {
    10     int n,i,j,re,sum,k;
    11     while(~scanf("%d",&n))
    12     {
    13          for(i=0;i<n;i++)
    14         {
    15             scanf("%d",&a[i]);
    16             a[i+n]=a[i];
    17         }
    18         sum=0;
    19         for(j=0;j<n;j++)
    20         {
    21             for(k=j+1;k<n;k++)
    22                 if(a[k]<a[j])
    23                     sum++;
    24         }
    25         re=sum;
    26         for(i=0;i<n;i++)
    27         {
    28             sum+=n-1-2*a[i];
    29             re=min(sum,re);
    30         }
    31         printf("%d
    ",re);
    32 
    33     }
    34     return 0;
    35 }
    View Code

    //memory:268KB  time:265ms

    方法二:当然就是线段树啦~,先求出出数列的inversion number,再用上面讲到的公式求其他的inversion number~~~

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int MAX=5555;
     7 int a[MAX<<2];
     8 
     9 void build(int l,int r,int x)
    10 {
    11     a[x]=0;
    12     if(l==r) return;
    13     int m=(l+r)>>1;
    14     build(l,m,x<<1);
    15     build(m+1,r,x<<1|1);
    16 }
    17 
    18 void update(int p,int l,int r,int x)
    19 {
    20     if(l==r)
    21     {
    22         a[x]++;
    23         return;
    24     }
    25     int m=(l+r)>>1;
    26     if(p<=m) update(p,l,m,x<<1);
    27     else
    28         update(p,m+1,r,x<<1|1);
    29     a[x]=a[x<<1]+a[x<<1|1];
    30 }
    31 
    32 int query(int le,int ri,int l,int r,int x)
    33 {
    34     if(le<=l && r<=ri)
    35         return a[x];
    36     int m=(l+r)>>1;
    37     int re=0;
    38     if(le<=m) re+=query(le,ri,l,m,x<<1);
    39     if(ri>m) re+=query(le,ri,m+1,r,x<<1|1);
    40     return re;
    41 }
    42 
    43 int x[MAX];
    44 int main()
    45 {
    46     int n;
    47     while(~scanf("%d",&n))
    48     {
    49         build(0,n-1,1);
    50         int sum=0;
    51         for(int i=0;i<n;i++)              //输入出数列,并求出出数列的inversion number~
    52         {
    53             scanf("%d",&x[i]);
    54             sum+=query(x[i],n-1,0,n-1,1);
    55             update(x[i],0,n-1,1);
    56         }
    57         int re=sum;
    58         for(int i=0;i<n;i++)
    59         {
    60             sum+=n-x[i]-x[i]-1;
    61             re=min(re,sum);              //找出最小的inversion number~
    62         }
    63         printf("%d
    ",re);
    64     }
    65     return 0;
    66 }

    //memory:280KB    time:46ms

    hdu2795  Billboard

    ......

  • 相关阅读:
    layer弹出相册层
    jquery日期和时间的插件精确到秒
    ztree树形菜单的增加删除修改和换图标
    瀑布流插件和模板插件
    使用easyui将json数据生成数据表格
    2013年回顾,2014年计划
    PHP trim去空格函数
    MySql中常用语句
    左右固定,中间自适应布局,中间栏优先加载
    HTML5的全局属性
  • 原文地址:https://www.cnblogs.com/teilawll/p/3249248.html
Copyright © 2020-2023  润新知