zoukankan      html  css  js  c++  java
  • BZOJ2883: gss2加强版

    题解:我们考虑到不包含重复元素 那么我们对每一个位置上的点都维护一个这个点的前驱节点 那么对于每个节点来说  都拥有两个关键字 问题转化为查询[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
    ",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
    ",ans);}
    	}
    }
    

      

    2883: gss2加强版

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 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

    Sample Output

    6
    13

    HINT

    2017.4.27新加数据一组  By nzhtl1477,时限放到20s,并重测

  • 相关阅读:
    如何制作静、动态库
    各种时间函数的恩与怨
    一文看懂Vim操作
    如何避免内存泄漏
    和leon一起学Vim
    shell的输入输出重定向
    和Leon一起从头学Git(六)
    和leon一起从头学Git(五)
    深入理解Linux高端内存
    和Leon一起从头学Git(四)
  • 原文地址:https://www.cnblogs.com/wang9897/p/9681375.html
Copyright © 2011-2022 走看看