题解:我们考虑到不包含重复元素 那么我们对每一个位置上的点都维护一个这个点的前驱节点 那么对于每个节点来说 都拥有两个关键字 问题转化为查询[l,r]前驱节点的值小于l的数的和 那我们可以用线段树套线段树解决此题
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
typedef struct node{
int id,vul;
friend bool operator<(node aa,node bb){
if(aa.vul==bb.vul)return aa.id<bb.id;
return aa.vul<bb.vul;
}
}node;
set<node>s;
set<node>::iterator ite,ip;
int d[MAXN<<2],cnt,n,m;
void debug(){
for(ite=s.begin();ite!=s.end();ite++)cout<<(*ite).id<<" "<<(*ite).vul<<endl;
}
typedef struct Node{
int l,r;ll sum;
}Node;
Node p[MAXN*61];
int key,id,a[MAXN];
void update1(int &x,int l,int r){
if(!x)x=++cnt;
p[x].sum+=key;
if(l==r)return ;
int mid=(l+r)>>1;
if(id<=mid)update1(p[x].l,l,mid);
else update1(p[x].r,mid+1,r);
}
void update(int rt,int l,int r,int t){
update1(d[rt],1,n);
if(l==r)return ;
int mid=(l+r)>>1;
if(t<=mid)update(rt<<1,l,mid,t);
else update(rt<<1|1,mid+1,r,t);
}
ll ans,ans1;
void querty1(int x,int l,int r){
if(1<=l&&r<=id){ans1+=p[x].sum;return ;}
int mid=(l+r)>>1;
if(1<=mid)querty1(p[x].l,l,mid);
if(id>mid)querty1(p[x].r,mid+1,r);
}
void querty(int rt,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){ans1=0;querty1(d[rt],1,n);ans+=ans1;return ;}
int mid=(l+r)>>1;
if(ql<=mid)querty(rt<<1,l,mid,ql,qr);
if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr);
}
int main(){
n=read();
inc(i,1,n){
a[i]=read();
ite=s.upper_bound((node){i,a[i]});
if(ite==s.begin())id=1,key=a[i],update(1,1,n,i);
else {
ite--;
if((*ite).vul!=a[i])id=1,key=a[i],update(1,1,n,i);
else id=(*ite).id+1,key=a[i],update(1,1,n,i);
}
s.insert((node){i,a[i]});
//cout<<i<<" "<<id<<" "<<a[i]<<endl;
}
m=read();char ch;int x,y;
while(m--){
scanf(" %c",&ch);x=read();y=read();
if(ch=='U'){
int pre,pre1;
ite=s.lower_bound((node){x,a[x]});ip=ite;
if(ite!=s.begin()){
ite--;
if((*ite).vul==a[x])id=(*ite).id+1;
else id=1;
ite++;
}
else id=1;
pre=id;
key=-a[x];update(1,1,n,x);
if(ite!=s.end()){
ite++;
if((*ite).vul==a[x]){
id=x+1;key=-a[x];update(1,1,n,(*ite).id);
id=pre;key=a[x];update(1,1,n,(*ite).id);
}#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=1e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
typedef struct node{
int id,vul;
friend bool operator<(node aa,node bb){
if(aa.vul==bb.vul)return aa.id<bb.id;
return aa.vul<bb.vul;
}
}node;
set<node>s;
set<node>::iterator ite,ip;
int d[MAXN<<2],cnt,n,m;
void debug(){
for(ite=s.begin();ite!=s.end();ite++)cout<<(*ite).id<<" "<<(*ite).vul<<endl;
}
typedef struct Node{
int l,r;ll sum;
}Node;
Node p[MAXN*61];
int key,id,a[MAXN];
void update1(int &x,int l,int r){
if(!x)x=++cnt;
p[x].sum+=key;
if(l==r)return ;
int mid=(l+r)>>1;
if(id<=mid)update1(p[x].l,l,mid);
else update1(p[x].r,mid+1,r);
}
void update(int rt,int l,int r,int t){
update1(d[rt],1,n);
if(l==r)return ;
int mid=(l+r)>>1;
if(t<=mid)update(rt<<1,l,mid,t);
else update(rt<<1|1,mid+1,r,t);
}
ll ans,ans1;
void querty1(int x,int l,int r){
if(1<=l&&r<=id){ans1+=p[x].sum;return ;}
int mid=(l+r)>>1;
if(1<=mid)querty1(p[x].l,l,mid);
if(id>mid)querty1(p[x].r,mid+1,r);
}
void querty(int rt,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){ans1=0;querty1(d[rt],1,n);ans+=ans1;return ;}
int mid=(l+r)>>1;
if(ql<=mid)querty(rt<<1,l,mid,ql,qr);
if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr);
}
int main(){
n=read();
inc(i,1,n){
a[i]=read();
ite=s.upper_bound((node){i,a[i]});
if(ite==s.begin())id=1,key=a[i],update(1,1,n,i);
else {
ite--;
if((*ite).vul!=a[i])id=1,key=a[i],update(1,1,n,i);
else id=(*ite).id+1,key=a[i],update(1,1,n,i);
}
s.insert((node){i,a[i]});
//cout<<i<<" "<<id<<" "<<a[i]<<endl;
}
m=read();char ch;int x,y;
while(m--){
scanf(" %c",&ch);x=read();y=read();
if(ch=='U'){
int pre,pre1;
ite=s.lower_bound((node){x,a[x]});ip=ite;
if(ite!=s.begin()){
ite--;
if((*ite).vul==a[x])id=(*ite).id+1;
else id=1;
ite++;
}
else id=1;
pre=id;
key=-a[x];update(1,1,n,x);
if(ite!=s.end()){
ite++;
if((*ite).vul==a[x]){
id=x+1;key=-a[x];update(1,1,n,(*ite).id);
id=pre;key=a[x];update(1,1,n,(*ite).id);
}
}
s.erase(ip);
ite=s.lower_bound((node){x,y});
pre=pre1=0;
if(ite!=s.end()&&(*ite).vul==y){
pre1=(*ite).id;
}
if(ite==s.begin())pre=1;
else{
ite--;
if((*ite).vul==y)pre=(*ite).id+1;
else pre=1;
}
if(pre1)key=-y,id=pre,update(1,1,n,pre1),key=y,id=x+1,update(1,1,n,pre1);
key=y;id=pre;update(1,1,n,x);
a[x]=y;s.insert((node){x,y});
}
else{ans=0;id=x;querty(1,1,n,x,y);printf("%lld\n",ans);}
}
}
}
s.erase(ip);
ite=s.lower_bound((node){x,y});
pre=pre1=0;
if(ite!=s.end()&&(*ite).vul==y){
pre1=(*ite).id;
}
if(ite==s.begin())pre=1;
else{
ite--;
if((*ite).vul==y)pre=(*ite).id+1;
else pre=1;
}
if(pre1)key=-y,id=pre,update(1,1,n,pre1),key=y,id=x+1,update(1,1,n,pre1);
key=y;id=pre;update(1,1,n,x);
a[x]=y;s.insert((node){x,y});
}
else{ans=0;id=x;querty(1,1,n,x,y);printf("%lld\n",ans);}
}
}
2883: gss2加强版
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 255 Solved: 66
[Submit][Status][Discuss]
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以内。
N<=100000,M<=100000
Output
对于每个Q操作返回一个值。
Sample Input
5
1 2 4 2 3
3
Q 2 4
U 4 7
Q 2 4
1 2 4 2 3
3
Q 2 4
U 4 7
Q 2 4
Sample Output
6
13
13
HINT
2017.4.27新加数据一组 By nzhtl1477,时限放到20s,并重测