2017东北地区赛D题 splay
来源:互联网 发布:家常菜谱软件下载 编辑:程序博客网 时间:2024/05/22 11:56
题意:25W个序列 支持三个操作:
1 给你一个长度为偶数的区间 交换区间相邻的元素 区间里 第1个和第2个换 第3个和第4个换 第5个和第6个换
2 给你一个长度为奇数的区间 将区间翻转
3 求区间的和
题解:将区间元素按下标奇偶分成2个splay 对于第1个操作直接交换区间 第2个操作由于是奇数长度的区间 所以把范围两个splay内的区间直接翻转就好了
PS:场上没有想到按奇偶分组 然后一直在操作一讨论奇偶性,然后发现这似乎是个不可能的操作?GG 最后两个半小时几乎什么都没有干,就这样划水还拿了一等,如果是ICPC估计就真的GG了....... (我用自己的数据测的是对的,直到我发blog时网上还没有挂出比赛题)
#include <bits/stdc++.h>using namespace std;#define pf printf#define ss system("pause");#define ps puts("");#define orz printf("orz\n");#define maxn 550000#define INF 0x3f3f3f3f#define sint long longint pfg;inline int getint(){ int res=0,f=1;char c; while(c=getchar(),c<'0'||c>'9'){if(c=='-')f=-1;} res=c-'0'; while(c=getchar(),c>='0'&&c<='9')res=res*10+c-'0'; return res*f;}int tr[maxn][2],fa[maxn],root,n,m,rt0,rt1;int v[maxn],val[maxn],a[maxn],siz[maxn],cnt;sint sum[maxn];bool rev[maxn];void pushup(int rt){ int l=tr[rt][0],r=tr[rt][1]; siz[rt]=siz[l]+siz[r]+1; sum[rt]=sum[l]+sum[r]+val[rt];}void pushdown(int rt){ if(rev[rt]) { int l=tr[rt][0],r=tr[rt][1]; rev[rt]^=1;rev[r]^=1;rev[l]^=1; swap(tr[l][0],tr[l][1]);swap(tr[r][0],tr[r][1]); }}void rotate(int x,int &rt){ int l,r,z,y; y=fa[x];z=fa[y]; if(x==tr[y][0]) l=0; else l=1;r=1^l; if(rt==y) rt=x; else { if(tr[z][0]==y) tr[z][0]=x; else tr[z][1]=x; } fa[x]=z;fa[y]=x;fa[tr[x][r]]=y; tr[y][l]=tr[x][r];tr[x][r]=y; pushup(y);pushup(x);}void splay(int x,int &rt){ int y,z; while(x!=rt) { y=fa[x];z=fa[y]; if(y!=rt) { if((tr[y][0]==x)^(tr[z][0]==y)) rotate(x,rt); else rotate(y,rt); } rotate(x,rt); }}int select(int now,int rk){ if(rev[now]) pushdown(now); int l=tr[now][0],r=tr[now][1]; int rak=siz[l]+1; if(rak==rk) return now; if(rak>rk) return select(l,rk); else return select(r,rk-rak);}void solve_rever(int x){ rev[x]^=1; swap(tr[x][0],tr[x][1]);}void build(int l,int r,int f){ if(l>r)return; int now=l,last=f; if(l==r) { sum[now]=val[now]=v[l]; fa[now]=last;siz[now]=1; if(l<f)tr[last][0]=now; else tr[last][1]=now; return; } int mid=(l+r)>>1;now=mid; build(l,mid-1,mid); build(mid+1,r,mid); val[now]=v[mid];fa[now]=last; pushup(now); if(mid<f)tr[last][0]=now; else tr[last][1]=now;}void get_trees(){ int l,r; cnt++;v[cnt]=0; l=cnt; for(int i=1;i<=n;i+=2) { cnt++;v[cnt]=a[i]; } cnt++;v[cnt]=0; r=cnt; rt1=(l+r)>>1; build(l,r,0); cnt++;v[cnt]=0; l=cnt; for(int i=2;i<=n;i+=2) { cnt++;v[cnt]=a[i]; } cnt++;v[cnt]=0; r=cnt; rt0=(l+r)>>1; build(l,r,0);}void solve_0(int l,int r){ int odd_rt =l/2+1; int even_rt=(l-1)/2+1; int len =(r-l+1)/2; int x1,y1; x1=select(rt1,odd_rt); y1=select(rt1,odd_rt+len+1); splay(x1,rt1); splay(y1,tr[x1][1]); int x0,y0; x0=select(rt0,even_rt); y0=select(rt0,even_rt+len+1); splay(x0,rt0); splay(y0,tr[x0][1]); swap(fa[tr[y1][0]],fa[tr[y0][0]]); swap(tr[y1][0],tr[y0][0]); pushup(y1);pushup(x1); pushup(y0);pushup(x0);}void dfs(int rt){ pushdown(rt); if(val[rt]) pf("%d %d %d\n",val[rt],sum[rt],fa[rt]); if(tr[rt][0]) dfs(tr[rt][0]); if(tr[rt][1]) dfs(tr[rt][1]);}void solve_1(int l, int r){ int odd_rt = l/2 + 1; int even_rt =(l-1)/2 + 1; int odd_len =(r-l)/2; int even_len = odd_len + 1; if (l&1) swap(odd_len,even_len); int x,y; x=select(rt1,odd_rt); y=select(rt1,odd_rt+odd_len+1); splay(x,rt1); splay(y,tr[x][1]); solve_rever(tr[y][0]); x=select(rt0,even_rt); y=select(rt0,even_rt+even_len+1); splay(x,rt0); splay(y,tr[x][1]); solve_rever(tr[y][0]);}sint qsum(int l, int r){ int odd_rt=l/2 + 1; int even_rt=(l-1)/2 + 1; int odd_len=(r+1)/2-l/2; int even_len=r/2-(l-1)/2; sint ans=0; int x,y; x=select(rt1,odd_rt); y=select(rt1,odd_rt+odd_len+1); splay(x,rt1); splay(y,tr[x][1]); ans +=sum[tr[y][0]]; x=select(rt0,even_rt); y=select(rt0,even_rt+even_len+1); splay(x,rt0); splay(y,tr[x][1]); ans +=sum[tr[y][0]]; return ans;}int main(){ n=getint(); for(int i=1;i<=n;i++) a[i]=getint(); get_trees(); int op,x,y,z; m=getint(); for(int i=1;i<=m;i++) { op=getint();x=getint();y=getint(); if(op==0) solve_0(x,y); if(op==1) solve_1(x,y); if(op==2) pf("%lld\n",qsum(x,y)); } return 0;}/*151 7 14 7 9 4 18 18 2 4 5 5 1 7 1152 1 140 5 100 11 141 6 82 2 72 2 130 5 82 8 120 4 132 6 102 8 122 9 122 1 120 2 90 6 9*/
阅读全文
0 0
- 2017东北地区赛D题 splay
- 2017黑龙江省赛+东北地区赛总结
- 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 D Coconuts HDU 5925
- (HDU 5927)Auxiliary Set 思维题 <2016CCPC东北地区大学生程序设计竞赛 - 重现赛 >
- 【HDU5925 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 D】【离散化 BFS】Coconuts 大地图少数坏点输出每个联通块的大小
- 【HDU5931 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 J】【线性规划 乱搞】Mission Possible 购买护甲和回复力和速度使得最小成本穿越D距离
- HDU 5922 Minimum’s Revenge(思维题)——2016CCPC东北地区大学生程序设计竞赛 - 重现赛
- hdu 5927 Auxiliary Set 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 F题(树状dp)
- (HDU 5922)Minimum’s Revenge 思维水题 <2016CCPC东北地区大学生程序设计竞赛 - 重现赛 >
- (HDU 5924)Mr. Frog’s Problem 思维水题 <2016CCPC东北地区大学生程序设计竞赛 - 重现赛 >
- Codeforces 675D Tree Construction (splay)
- 2017第十一届东北地区程序设计竞赛总结2017/5/14
- HDOJ 5929 Basic Data Structure 【2016CCPC东北地区赛】STL
- 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 部分题解
- CCPC第十一届东北地区大学生程序设计竞赛(2017) 总结
- Splay 入门题
- splay入门题---中位数
- bzoj4144 splay模板题
- 1.2 第一个Windows应用程序实例
- 与Mysql互交(增/删/改/查)
- Java四种线程池的使用
- servlet多请求处理
- [BZOJ4828][Hnoi2017]大佬-DP+DFS
- 2017东北地区赛D题 splay
- LeetCode -- 96. Unique Binary Search Trees
- mysql 状态查询
- Java监听器
- POJ3662-Telephone Lines
- opengles(一) hello world
- mongoose模糊查询+限制条件
- [PAT-乙级]1046.划拳
- 扩展ThreadPoolExecutor