• poj 3468 A Simple Problem with Integers 数据结构


    线段树水题

    写splay练手

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 using namespace std;
      6 #define MAXN 100000+100
      7 struct node
      8 {
      9     long long sum,father,left,right,adt,cnt,num;
     10 };
     11 node tree[MAXN];
     12 int top=0,n,m,root;
     13 long long a[MAXN];
     14 void update(int x)
     15 {
     16     tree[x].sum=tree[tree[x].left].sum+tree[tree[x].right].sum+tree[x].num;
     17     tree[x].cnt=tree[tree[x].left].cnt+tree[tree[x].right].cnt+1;
     18 }
     19 void push_down(int x)
     20 {
     21     tree[tree[x].left].adt+=tree[x].adt;
     22     tree[tree[x].left].num+=tree[x].adt;
     23     tree[tree[x].left].sum+=tree[x].adt*tree[tree[x].left].cnt;
     24     tree[tree[x].right].adt+=tree[x].adt;
     25     tree[tree[x].right].sum+=tree[x].adt*tree[tree[x].right].cnt;
     26     tree[tree[x].right].num+=tree[x].adt;
     27     tree[x].adt=0;
     28 }
     29 
     30 void left_rotate(int x)
     31 {
     32     int y=tree[x].father,z=tree[x].left;
     33     if(y==tree[tree[y].father].left) tree[tree[y].father].left=x;
     34     else tree[tree[y].father].right=x;
     35     tree[x].father=tree[y].father;
     36     tree[x].left=y;
     37     tree[y].right=z;
     38     tree[y].father=x;
     39     tree[z].father=y;
     40     update(y); update(x);
     41 }
     42 
     43 void right_rotate(int x)
     44 {
     45     int y=tree[x].father,z=tree[x].right;
     46     if(y==tree[tree[y].father].right) tree[tree[y].father].right=x;
     47     else tree[tree[y].father].left=x;
     48     tree[x].father=tree[y].father;
     49     tree[x].right=y;
     50     tree[y].left=z;
     51     tree[y].father=x;
     52     tree[z].father=y;
     53     update(y); update(x);
     54 }
     55 
     56 void splay(int rootnew,int x)
     57 {
     58     push_down(x);
     59     int fa=tree[rootnew].father;
     60     while(tree[x].father!=fa)
     61     {
     62         int y=tree[x].father;
     63         int z=tree[y].father;
     64         if(z==fa)
     65         {
     66             if(x==tree[y].left) right_rotate(x);
     67             else left_rotate(x);
     68             break;
     69         }
     70         if(y==tree[z].left)
     71             if(x==tree[y].left) right_rotate(y),right_rotate(x);
     72             else left_rotate(x),right_rotate(x);
     73         else
     74             if(x==tree[y].left) right_rotate(x),left_rotate(x);
     75             else left_rotate(y),left_rotate(x);
     76     }
     77     if(rootnew==root) 
     78         root=x;
     79 }
     80 int newnode(int lnum,int rnum,int value)
     81 {
     82     tree[++top].left=lnum; tree[top].right=rnum;
     83     tree[lnum].father=tree[rnum].father=top;
     84     tree[top].num=value;
     85     update(top);
     86     return top;
     87 }
     88 int build_tree(int l,int r)
     89 {
     90     if(l>r) return 0;
     91     int mid=(l+r)/2;
     92     int lnum=build_tree(l,mid-1);
     93     int rnum=build_tree(mid+1,r);
     94     return newnode(lnum,rnum,a[mid]);
     95 }
     96 void find(int root,int pos)
     97 {
     98     int x=root;
     99     while(push_down(x),tree[tree[x].left].cnt+1!=pos)
    100     {
    101         if(pos<=tree[tree[x].left].cnt)
    102             x=tree[x].left;
    103         else
    104             pos-=tree[tree[x].left].cnt+1, x=tree[x].right;
    105     }
    106     splay(root,x);
    107 }
    108 void query(int x,int y)
    109 {
    110     find(root,x-1);        
    111     find(tree[root].right,y-x+2);
    112     printf("%lld\n",(tree+tree[tree[root].right].left)->sum);
    113 }
    114 void add(int x,int y,long long z)
    115 {
    116     find(root,x-1);
    117     find(tree[root].right,y-x+2);
    118     int p=tree[tree[root].right].left;
    119     tree[p].sum+=z*tree[p].cnt;
    120     tree[p].adt+=z;
    121     tree[p].num+=z;
    122 }
    123 
    124 int main()
    125 {
    126     int i,j;
    127     char c[10];
    128     memset(tree,0,sizeof(tree));
    129     memset(a,0,sizeof(a));
    130     scanf("%d%d",&n,&m);
    131     for(i=2;i<=n+1;i++)
    132         scanf("%lld",a+i);
    133     root=build_tree(1,n+2);
    134     int x,y;
    135     long long z;
    136     for(i=1;i<=m;i++)
    137     {
    138         scanf("%s",c);
    139         if(c[0]=='Q')
    140         {
    141             scanf("%d%d",&x,&y);
    142             query(x+1,y+1);
    143         }
    144         else
    145         {
    146             scanf("%d%d%lld",&x,&y,&z);
    147             add(x+1,y+1,z);
    148         }
    149     }
    150     return 0;
    151 }
    152             
  • 相关阅读:
    nodejs 模板引擎jade的使用
    Underscore.js 入门-常用方法介绍
    Underscore.js 入门
    画菱形或者尖角
    微信小程序 bindcontroltap 绑定 没生效
    js--敏感词屏蔽
    js生成二维码 中间有logo
    移除input在type="number"时的上下箭头
    js获取当前域名、Url、相对路径和参数以及指定参数
    hihocoder 1931 最短管道距离
  • 原文地址:https://www.cnblogs.com/myoi/p/2513961.html
Copyright © 2020-2023  润新知