首页 > 代码库 > POJ3468---A Simple Problem with Integers
POJ3468---A Simple Problem with Integers
此题简单的做法自然是 线段树 或树状数组,splay只是为了练手。。依旧 是学习bin神的模板,写了一发之后理解更深了。
1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 typedef unsigned long long ull; 16 typedef long long ll; 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-8; 19 const int maxn = 1e5+100; 20 ll add[maxn],sum[maxn]; 21 int ch[maxn][2],siz[maxn],key[maxn],a[maxn]; 22 int pre[maxn]; 23 int tot1,root; 24 void new_node(int &r,int father,int k) 25 { 26 r = ++tot1; 27 pre[r] = father; 28 siz[r] = 1; 29 add[r] = 0; 30 key[r] = k; 31 sum[r] = k; 32 ch[r][0] = ch[r][1] = 0; 33 } 34 35 void update(int r,int val) 36 { 37 if (r == 0) 38 return ; 39 add[r] += val; 40 key[r] += val; 41 sum[r] += (ll)val * siz[r]; 42 } 43 44 void push_down(int x) 45 { 46 if (add[x]) 47 { 48 update(ch[x][0],add[x]); 49 update(ch[x][1],add[x]); 50 add[x] = 0; 51 } 52 } 53 void push_up(int x) 54 { 55 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; 56 sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + key[x]; 57 } 58 void build(int &x,int l,int r,int father) 59 { 60 if (l > r) 61 return; 62 int mid = (l + r) >> 1; 63 new_node(x,father,a[mid-1]); 64 build(ch[x][0],l,mid-1,x); 65 build(ch[x][1],mid+1,r,x); 66 push_up(x); 67 } 68 void init(int n) 69 { 70 tot1 = 0; 71 root = 0; 72 new_node(root,0,-1); 73 new_node(ch[root][1],root,-1); 74 for (int i = 0; i < n; i++) 75 scanf ("%d",a+i); 76 build(ch[ch[root][1]][0],1,n,ch[root][1]); 77 push_up(ch[root][1]); 78 push_up(root); 79 } 80 void Rotate(int x,int kind) 81 { 82 int y = pre[x]; 83 push_down(y); 84 push_down(x); // 标记下传 85 86 ch[y][!kind] = ch[x][kind]; 87 pre[ch[x][kind]] = y; 88 ch[x][kind] = y; 89 if (pre[y]) 90 ch[pre[y]][ch[pre[y]][1] == y] = x; 91 pre[x] = pre[y]; 92 pre[y] = x; 93 push_up(y); // ??? 94 } 95 void Splay(int r,int goal) 96 { 97 push_down(r); 98 while (pre[r] != goal) 99 {100 if (pre[pre[r]] == goal)101 Rotate(r,ch[pre[r]][0] == r);102 else103 {104 int y = pre[r];105 int kind = (ch[pre[y]][0] == y);106 if (ch[y][kind] == r)107 {108 Rotate(r,!kind);109 Rotate(r,kind);110 }111 else112 {113 Rotate(y,kind);114 Rotate(r,kind);115 }116 }117 }118 push_up(r);119 if (goal == 0)120 root = r;121 }122 int Get_kth(int r,int k)123 {124 push_down(r);125 int t = siz[ch[r][0]] + 1;126 if (k == t)127 return r;128 if (t > k)129 Get_kth(ch[r][0],k);130 else131 Get_kth(ch[r][1],k-t);132 }133 void ADD(int l,int r,int val)134 {135 Splay(Get_kth(root,l),0);136 Splay(Get_kth(root,r+2),root);137 update(ch[ch[root][1]][0],val);138 push_up(ch[root][1]);139 push_up(root);140 }141 ll query(int l,int r)142 {143 Splay(Get_kth(root,l),0);144 Splay(Get_kth(root,r+2),root);145 return sum[ch[ch[root][1]][0]];146 }147 int main(void)148 {149 #ifndef ONLINE_JUDGE150 freopen("in.txt","r",stdin);151 #endif152 int n,q;153 while (~scanf ("%d%d",&n,&q))154 {155 init(n);156 char op[8];157 while (q--)158 {159 scanf ("%s",op);160 if (op[0] == ‘C‘)161 {162 int x,y,v;163 scanf ("%d%d%d",&x,&y,&v);164 ADD(x,y,v);165 }166 if (op[0] == ‘Q‘)167 {168 int x,y;169 scanf ("%d%d",&x,&y);170 printf("%lld\n",query(x,y));171 }172 }173 }174 return 0;175 }
POJ3468---A Simple Problem with Integers
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。