【BZOJ2883】gss2加强版
来源:互联网 发布:快思聪中控编程教程 编辑:程序博客网 时间:2024/05/01 12:43
Description
给你N个数,你需要支持一下两种操作。
U x y,讲第x个数修改成y;
Q x y,计算从第x个数至第y个数中不同数的和并输出。如对于一段数{1,2,3,2,7},它的值是13(1+2+3+7)。
Input
第一行N表示数的个数(1<=N<=100000);
第二行包含这N个数;
第三行M表示操作次数(1<=N<=100000);
接下来M行每行三个数表示题目描述的操作。
所有的输入均在int以内。
Output
对于每个Q操作返回一个值。
Sample Input
5
1 2 4 2 3
3
Q 2 4
U 4 7
Q 2 4
Sample Output
6
13
HINT
【数据规模和约定】
30%:N<=3000,M<=3000
100%:N<=100000,M<=100000。
Source
把询问离散.
考虑对每个数维护上一次出现的位置,相同数值的数把这些位置丢进set.
所以对于修改用set改前驱后继搞一搞.
一个询问[l,r],其实就是问[l,r]内有多少数上一次出现的位置小于l,显然可以树套树做.
我本来以为线段树套动态开点权值线段树比平衡树常数小,没想到我的做法比Claris的线段树套平衡树慢那么多QAQ
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<set>#include<algorithm>#define MAXN 100010#define SIZE 6000010#define LL long long#define GET (ch>='0'&&ch<='9')#define ln rt<<1#define rn rt<<1|1using namespace std;int n,m,cnt;int pre[MAXN*2],a[MAXN],sta[MAXN*2],top;struct query { int opt,x,y; }q[MAXN];int root[MAXN<<2];LL sum[SIZE];int ls[SIZE],rs[SIZE];set<int> S[MAXN*3];inline void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}void Modify(int &rt,int l,int r,int x,int val)//modify in dynamic segment tree{ if (!rt) rt=++cnt; if (l==r) { sum[rt]+=val;return; } int mid=(l+r)>>1; if (x<=mid) Modify(ls[rt],l,mid,x,val); else Modify(rs[rt],mid+1,r,x,val); sum[rt]=sum[ls[rt]]+sum[rs[rt]];}void modify(int rt,int l,int r,int x1,int x2,int val)//modify in ordinary segment tree{ Modify(root[rt],0,top,x2,val); if (l==r) return; int mid=(l+r)>>1; if (x1<=mid) modify(ln,l,mid,x1,x2,val); else modify(rn,mid+1,r,x1,x2,val);}LL Query(int rt,int L,int R,int l,int r)//query in dynamic segment tree{ if (!rt) return 0; if (L>=l&&R<=r) return sum[rt]; int mid=(L+R)>>1;LL ret=0; if (l<=mid) ret+=Query(ls[rt],L,mid,l,r); if (r>mid) ret+=Query(rs[rt],mid+1,R,l,r); return ret;}LL query(int rt,int L,int R,int l,int r)//query in ordinary segment tree{ if (L>=l&&R<=r) return Query(root[rt],0,top,0,l-1); int mid=(L+R)>>1;LL ret=0; if (l<=mid) ret+=query(ln,L,mid,l,r); if (r>mid) ret+=query(rn,mid+1,R,l,r); return ret;}int main(){ in(n);char ch[2];int x,y,prev; for (int i=1;i<=n;i++) in(a[i]),sta[++top]=a[i]; in(m); for (int i=1;i<=m;i++) { scanf("%s",ch);in(q[i].x);in(q[i].y); if (ch[0]=='Q') q[i].opt=0; else q[i].opt=1,sta[++top]=q[i].y; } sort(sta+1,sta+top+1);top=unique(sta+1,sta+top+1)-sta; for (int i=1;i<=n;i++) { int val=lower_bound(sta+1,sta+top+1,a[i])-sta; modify(1,0,n,i,pre[val],a[i]);pre[val]=i;S[val].insert(i); } for (int i=1;i<=m;i++) { if (!q[i].opt) printf("%lld\n",query(1,0,n,q[i].x,q[i].y)); else { x=lower_bound(sta+1,sta+top+1,a[q[i].x])-sta; y=lower_bound(sta+1,sta+top+1,q[i].y)-sta; set<int>::iterator it=S[x].lower_bound(q[i].x);prev=0; if (it!=S[x].begin()) --it,prev=*it,++it; modify(1,0,n,q[i].x,prev,-a[q[i].x]); if ((++it)!=S[x].end()) modify(1,0,n,*it,q[i].x,-a[*it]),modify(1,0,n,*it,prev,a[*it]); --it;S[x].erase(it);prev=0; a[q[i].x]=q[i].y;S[y].insert(q[i].x);it=S[y].lower_bound(q[i].x); if (it!=S[y].begin()) --it,prev=*it,++it; modify(1,0,n,q[i].x,prev,a[q[i].x]); if ((++it)!=S[y].end()) modify(1,0,n,*it,prev,-a[*it]),modify(1,0,n,*it,q[i].x,a[*it]); } }}
1 0
- 【BZOJ2883】gss2加强版
- [线段树套平衡树] BZOJ 2883 gss2加强版
- SPOJ GSS2
- SPOJ GSS2 离线线段树
- SPOJ 1557 GSS2 线段树
- 加强版 X5
- Edit控件加强版
- 信封问题加强版
- LIS加强版
- GPS 数据格式加强版
- 加强版理发师问题
- 动物统计加强版
- 下拉菜单加强版
- helloworld驱动加强版
- hdu4521 加强版LIS
- silverlight 加强版GroupBox
- 动物统计加强版
- 动物统计加强版
- iOS 开发中用模拟器跑程序时cell的分割线一直不显示
- 使用 ImageLoader报 UIL doesn't support scheme(protocol) by default 错误
- 常用adb命令大全
- 使用Dialog自定义菜单
- IDEA + SVN 导入eclipse项目
- 【BZOJ2883】gss2加强版
- LayoutInflater深入理解
- ld: symbol(s) not found for architecture i386
- SOAP消息机制简介
- 移动端H5各种各样的列表的制作方法(四) by FungLeo
- 其实xml解析很快的。很方便的,用superxmlparse
- Elasticsearch与Solr 选型
- Intellij clear read only status
- 使用winSCP+putty发布项目至远程服务器