HDU1166 敌兵布阵 splay

题意:中文题。

解题思路:splay

解题代码:

  1 // File Name: hdu1166.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年04月02日 星期四 18时21分48秒
  4
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #define LL long long
 25
 26 using namespace std;
 27 const int maxn = 50005;
 28 int t,n;
 29 struct SplayTree{
 30     int sz[maxn];
 31     int ch[maxn][2];
 32     int pre[maxn];
 33     int root ,top1,top2;
 34     int ss[maxn],que[maxn];
 35
 36     inline void Rotate(int x,int f){
 37         int y = pre[x];
 38         push_down(y);
 39         push_down(x);
 40         ch[y][!f] = ch[x][f];
 41         pre[ch[x][f]] = y ;
 42         pre[x] = pre[y];
 43         if(pre[x]) ch[pre[y]][ch[pre[y]][1] == y] = x;
 44         ch[x][f] = y ;
 45         pre[y] = x ;
 46         push_up(y);
 47     }
 48     inline void Splay(int x, int goal){
 49          push_down(x);
 50          while(pre[x] != goal){
 51             if(pre[pre[x]] == goal){
 52                 Rotate(x, ch[pre[x]][0] == x);
 53             }else{
 54                int y = pre[x],z = pre[y];
 55                int f = (ch[z][0] == y);
 56                if(ch[y][f] == x){
 57                     Rotate(x,!f) , Rotate(x,f);
 58                }else{
 59                     Rotate(y,f) , Rotate(x,f);
 60                }
 61             }
 62          }
 63          push_up(x);
 64          if(goal ==  0) root = x;
 65     }
 66     inline void RotateTo(int k ,int goal){
 67         int x = root;
 68         push_down(x);
 69         while(sz[ch[x][0]] != k ){
 70             if(k < sz[ ch[x][0] ]){
 71                 x = ch[x][0];
 72             }else{
 73                 k -= (sz[ch[x][0]] + 1);
 74                 x = ch[x][1];
 75             }
 76             push_down(x);
 77         }
 78         Splay(x,goal);
 79     }
 80     inline void erase(int x){
 81         int father = pre[x];
 82         int head = 0 , tail = 0 ;
 83         for(que[tail ++] = x ; head < tail ;head ++){
 84             ss[top2++] = que[head];
 85             if(ch[que[head] ][0]) que[tail ++] = ch[que[head]][0];
 86             if(ch[que[head] ][1]) que[tail ++] = ch[que[head]][1];
 87         }
 88         ch[father][ch[father][1] == x] = 0 ;
 89         push_up(father);
 90     }
 91     inline void NewNode(int &x,int c){
 92          if(top2) x = ss[--top2];
 93          else x = ++top1;
 94          ch[x][0] = ch[x][1] = pre[x] = 0 ;
 95          sz[x] = 1;
 96          val[x] = sum[x] = c;
 97     }
 98     inline void push_down(int x){
 99
100     }
101     inline void push_up(int x){
102         sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
103         sum[x] = val[x] + sum[ch[x][0]] + sum[ch[x][1]];
104     }
105     inline void makeTree(int &x,int l ,int r,int f){
106         if(l > r) return ;
107         int m = (l + r ) >> 1;
108         NewNode(x,num[m]);
109         makeTree(ch[x][0],l,m-1,x);
110         makeTree(ch[x][1],m+1,r,x);
111         pre[x] = f;
112         push_up(x);
113     }
114     inline void init(int n){
115         ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0 ;
116         sum[0] = 0 ;
117         root = top1 = 0 ;
118         NewNode(root,-1);
119         NewNode(ch[root][1],-1);
120         pre[top1] = root;
121         sz[root] = 2;
122
123         for(int i =  1 ;i <= n;i ++) scanf("%d",&num[i]);
124         makeTree(ch[ch[root][1]][0],1,n,ch[root][1]);
125         push_up(ch[root][1]);
126         push_up(root);
127
128     }
129     inline void update(int l,int v){
130       RotateTo(l,0);
131       val[root] += v;
132     }
133     inline void query(int l , int r){
134        RotateTo(l-1,0);
135        RotateTo(r+1,root);
136        printf("%lld\n",sum[ch[ch[root][1]][0]]);
137     }
138     int num[maxn];
139     LL sum[maxn];
140     int val[maxn];
141 }spt;
142 char str[10];
143 int ta,tb;
144 int main(){
145     scanf("%d",&t);
146     for(int CA = 1; CA <= t ; CA ++)
147     {
148             printf("Case %d:\n",CA);
149             scanf("%d",&n);
150             spt.init(n);
151             while(scanf("%s",str)!= EOF)
152             {
153                 if(str[0] == ‘E‘)
154                     break;
155                 scanf("%d %d",&ta,&tb);
156                 if(str[0] == ‘Q‘)
157                 {
158                     spt.query(ta,tb);
159                 }else if(str[0] == ‘A‘){
160                     spt.update(ta,tb);
161                 }else if(str[0] == ‘S‘){
162                     spt.update(ta,-tb);
163                 }else {
164                     break;
165                 }
166                 //printf("%lld\n",spt.sum[1]);
167             }
168     }
169
170 return 0;
171 }

时间: 2024-10-25 23:11:07

HDU1166 敌兵布阵 splay的相关文章

【线段树】hdu1166敌兵布阵

/* 水水的线段树点修改: ---------------------------------------------------------------- void build(int l,int r,int o)建树 { int mid = (l + r) / 2; a[o].left = l; a[o].right = r; a[o].num = 0; if(a[o].left == a[o].right)到达叶子节点 return ; build(l, mid, lc);向左走 buil

HDU1166敌兵布阵

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 43607    Accepted Submission(s): 18499 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

hdu1166敌兵布阵&amp;&amp;hdu1754I Hate It(线段树入门)

单点更新是最最基础的线段树,只更新叶子节点,然后把信息用pushup这个函数更新上来. http://acm.hdu.edu.cn/showproblem.php?pid=1166 update单点更新,query区域求和. #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 200001 using namespace std; s

hdu-1166敌兵布阵

这个题目就是考察线段树的基本用法,我自己打了代码,其实就是照模板来的,大概思想已经弄懂了.用c++不能过,说我超时,就改成c的读入读出,这坑爹的过了.我最爱的c++,你肿么了... 这是ac的代码: #include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m; int num[100005]; struct H { int l,r,sum; }trees[30000

HDU1166 敌兵布阵 树状数组水题

中文题目,很简单的题目,区间求和,当然对于线段树来说也很水,为了练习一下树状数组,多做做水题吧,加深理解,并且打好基础,我算是被没打好基础给吓坏了,宁可多花几个小时 刷刷水题扎实点, 很裸的题目 操作也很裸,了解树状数组的肯定能做 #include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string&g

HDU1166 敌兵布阵(树状数组)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 60510    Accepted Submission(s): 25649 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

hdu1166 敌兵布阵(线段树 求区间和 更新点)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 59427    Accepted Submission(s): 25098 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又開始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务

HDU-1166 敌兵布阵(线段树,点变换+段查询)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 97419    Accepted Submission(s): 41227 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就

HDU1166敌兵布阵(线段树单点更新)

线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩. [以下以 求区间最大值为例] 先看声明