uva Array Transformer

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3154

题意:给一个序列,然后是操作:
L,R,V,P:求区间[L,R]中小于V的个数k,然后更新 P位置的值为k*u/(R-L+1)。
输出最后的序列。
思路:线段树 套 sbt.
View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 300005;
int ch[maxn*25][2];
int sz[maxn*25];
LL val[maxn*25];
LL as[maxn];
LL bs[maxn];
int ds[maxn];
int tot;
LL n,m,u;
struct nd{
    int rt;
    inline void clr(){rt=0;}
    inline void LRrot(int &x,int f)
    {
        int k = ch[x][!f];
        ch[x][!f] = ch[k][f];
        ch[k][f] = x;
        sz[k] = sz[x];
        sz[x] = sz[ch[x][f]] + sz[ch[x][!f]] + 1;
        x = k;
    }
    //调整处理
    void Maintain(int &r,bool flag)
    {
        if(flag){//更新右子树
            if(sz[ch[ch[r][1]][1]] > sz[ch[r][0]])
                LRrot(r,0);
            else if(sz[ch[ch[r][1]][0]] > sz[ch[r][0]]){
                LRrot(ch[r][1],1);
                LRrot(r,0);
            }else return ;
        }else{//更新在左子树
            if(sz[ch[ch[r][0]][0]] > sz[ch[r][1]])
                LRrot(r,1);
            else if(sz[ch[ch[r][0]][1]] > sz[ch[r][1]]){
                LRrot(ch[r][0],0);
                LRrot(r,1);
            }else return;
        }
        //更新子树,然后再更新根,直到平衡为止
        Maintain(ch[r][0],false);
        Maintain(ch[r][1],true);
        Maintain(r,false);
        Maintain(r,true);
    }
    void Insert(int &r,LL k)
    {
        if(r==0){
            r = ++tot;
            ch[r][0] = ch[r][1] = 0;
            sz[r] = 1;
            val[r] = k;
        }else{
            sz[r]++;
            if(k<val[r])
                Insert(ch[r][0],k);
            else Insert(ch[r][1],k);
            Maintain(r,k>=val[r]);
        }
    }
    int Remove(int &r,LL k)
    {
        int dval;
        if(!r)return 0;
        sz[r]--;
        if(val[r]==k||(ch[r][0]==0&&k<val[r])||(ch[r][1]==0&&k>val[r])){
            dval = val[r];
            if(ch[r][0]&&ch[r][1])
                val[r] = Remove(ch[r][0],k+1);
            else
                r = ch[r][0]+ch[r][1];
        }else dval = Remove(ch[r][k>val[r]],k);
        return dval;
    }
    int GetRank(int &r,LL k)
    {
        if(!r)return 0;
        if(k<val[r])return GetRank(ch[r][0],k);
        else if(k>=val[r])
            return GetRank(ch[r][1],k)+sz[ch[r][0]] + 1;
        return sz[ch[r][0]]+1;
    }
}T[maxn*4];

void build(int rt,int l,int r)
{
    int md = (l + r)>> 1;
    T[rt].clr();
    int j = 0;
    for(int i = l; i <= r; ++ i)bs[j++]=as[i];
    sort(bs,bs+j);
    for(int i = j / 2; i < j; ++ i)
        T[rt].Insert(T[rt].rt,bs[i]);
    for(int i = 0; i < j / 2; ++ i)
        T[rt].Insert(T[rt].rt,bs[i]);
    if(l==r){
        ds[l]=rt;
        return;
    }
    build(rt<<1,l,md);
    build(rt<<1|1,md+1,r);
}
int ans;
void query(int rt,int l,int r,int L,int R,LL v)
{
    int md = (l + r) >> 1;
    if(L<=l && r<=R){
        ans += T[rt].GetRank(T[rt].rt,v);
        return;
    }
    if(L<=md)query(rt<<1,l,md,L,R,v);
    if(R>md )query(rt<<1|1,md+1,r,L,R,v);
}
void update(int rt,LL v,LL rv)
{
    while(rt){
        T[rt].Remove(T[rt].rt,rv);
        T[rt].Insert(T[rt].rt,v);
        rt /= 2;
    }
}
//下面分别是输入输出优化
inline int scan(){
    int res=0,ch;
    while(!((ch=getchar())>='0' && ch<='9'))
    if(ch==EOF) return 1<<30;    res=ch-'0';
    while((ch=getchar())>='0' && ch<='9')
    res=res*10+(ch-'0');
    return res;
}
inline void printf_(LL num){
    bool flag=false;
    if(num<0){
        putchar('-');
        num=-num;
    }
    LL ans[30],top=0;
    while(num!=0){
        ans[top++]=num%10;
        num/=10;
    }
    if(top==0)
        putchar('0');
    for(int i=top-1;i>=0;i--){
        char ch=ans[i]+'0';
        putchar(ch);
    }
    puts("");
}
int main()
{
    LL i,l,r,p,v;
 //   freopen("D:\\in.txt","r",stdin);
 //   freopen("D:\\out1.txt","w",stdout);
    while(scanf("%lld %lld %lld",&n,&m,&u)==3){
        for(i = 1; i <= n; ++ i)as[i]=scan();
        tot = 0;
        build(1,1,n);
        for(i=0;i<m;++i){
            l=scan();r=scan();v=scan();p=scan();
            ans = 0;
            query(1,1,n,l,r,v-1);
            LL t = u * ans / (r - l + 1);
        //    printf("-> %d %lld\n",ans,t);
            if(t^as[p]){
                update(ds[p],t,as[p]);
                as[p] = t;
            }
        }
        for(i = 1; i <= n; ++ i)printf_(as[i]);
    }
    return 0;
}

线段树 套 treap  卡死了。

YM刘汝佳

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<time.h>
#define lowbit(x) (x)&(-x)
#define LL long long
using namespace std;
const int maxn = 300005;
LL val[maxn*23];
int ch[maxn*23][2];
int sz[maxn*23];
int cnt[maxn*23];
int fix[maxn*23];
int ds[maxn];
LL bs[maxn];
LL as[maxn],n,m,u;
int size;
LL f1,f2,f3,ans;

struct treap{
    int rt;
    inline void clr(){rt = -1;}
    inline void pushUp(int k){
        if(k<0)return;
        sz[k] = cnt[k];
        if(ch[k][0]!=-1)sz[k] += sz[ch[k][0]];
        if(ch[k][1]!=-1)sz[k] += sz[ch[k][1]];
    }
    inline void rot(int &x,int f){
        LL y = ch[x][f];
        ch[x][f] = ch[y][!f];
        ch[y][!f] = x;
        pushUp(x);
        x = y;
    }
    inline void insert(int &k,LL v){
        if(k==-1){
            k = ++size;
            ch[k][0] = ch[k][1] = -1;
            val[k] = v;
            cnt[k] = 1;
       //     f3=(f1+f2);
       //     f1=f2;f2=f3;
            fix[k] = rand();
        } else if(v < val[k]){
            insert(ch[k][0],v);
            if(fix[ch[k][0]]>fix[ch[k][1]])
            rot(k,0);
        } else{
            insert(ch[k][1],v);
            if(fix[ch[k][1]]>fix[ch[k][0]])
            rot(k,1);
        }
        pushUp(k);
    }
    inline void remove(int &k,LL v){
        if(k==-1)return;
        if(v < val[k]) remove(ch[k][0],v);
        else if(v > val[k]) remove(ch[k][1],v);
        else{
            if(ch[k][0]+ch[k][1]==-2) k = -1;
            else if(ch[k][0]==-1)k=ch[k][1];
            else if(ch[k][1]==-1)k=ch[k][0];
            else if(fix[ch[k][0]] < fix[ch[k][1]]){
                rot(k,1);
                remove(ch[k][0],v);
            } else{
                rot(k,0);
                remove(ch[k][1],v);
            }
        }
        pushUp(k);
    }
    inline void query(int k,LL v){
        if(k<0)return;
        int kl = ch[k][0];
        if(val[k]<=v){
            ++ans;
            if(kl>-1)
            ans+=sz[kl];
        }
        query(ch[k][val[k]<=v],v);
    }
    inline void debug(){
        printf("rt %d\n",rt);
        Treaval(rt);
    }
    inline void Treaval(int x){
        if(x>=0){
            Treaval(ch[x][0]);
            printf("?áμ?%2d:×ó?ù×ó %2d óò?ù×ó %2d size = %2d ,val = %2lld\n",x,ch[x][0],ch[x][1],sz[x],val[x]);
            Treaval(ch[x][1]);
        }
    }
}T[maxn*4];
void build(int rt,int l,int r)
{
    int md = (l + r)>> 1;
    T[rt].clr();
    int j = 0;
    for(int i = l; i <= r; ++ i)bs[j++]=as[i];
    sort(bs,bs+j);
    for(int i = j / 2; i < j; ++ i)
        T[rt].insert(T[rt].rt,bs[i]);
    for(int i = 0; i < j / 2; ++ i)
        T[rt].insert(T[rt].rt,bs[i]);
    if(l==r){
        ds[l]=rt;
        return;
    }
    build(rt<<1,l,md);
    build(rt<<1|1,md+1,r);
}
void query(int rt,int l,int r,int L,int R,LL v)
{
    int md = (l + r) >> 1;
    if(L<=l && r<=R){
        T[rt].query(T[rt].rt,v);
        return;
    }
    if(L<=md)query(rt<<1,l,md,L,R,v);
    if(R>md )query(rt<<1|1,md+1,r,L,R,v);
}
void update(int rt,LL v,LL rv)
{
    while(rt){
        if(rv<=1e9)
        T[rt].remove(T[rt].rt,rv);
        if(v<=1e9)
        T[rt].insert(T[rt].rt,v);
        rt /= 2;
    }
}
inline int scan(){
    int res=0,ch;
    while(!((ch=getchar())>='0' && ch<='9'))
    if(ch==EOF) return 1<<30;    res=ch-'0';
    while((ch=getchar())>='0' && ch<='9')
    res=res*10+(ch-'0');
    return res;
}
inline void printf_(LL num){
    bool flag=false;
    if(num<0){
        putchar('-');
        num=-num;
    }
    LL ans[30],top=0;
    while(num!=0){
        ans[top++]=num%10;
        num/=10;
    }
    if(top==0)
        putchar('0');
    for(int i=top-1;i>=0;i--){
        char ch=ans[i]+'0';
        putchar(ch);
    }
    puts("");
}
int main()
{
    LL i,l,r,p,v,k;
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out1.txt","w",stdout);
    while(scanf("%lld %lld %lld",&n,&m,&u)==3){
        for(i = 1; i <= n; ++ i)as[i]=scan();
        srand(time(0));
        size = 1; f1=1000;f2=50000;
        build(1,1,n);
        for(i=0;i<m;++i){
            l=scan();r=scan();v=scan();p=scan();
            if(l>r)l^=r^=l^=r;
            ans = 0;
            query(1,1,n,l,r,v-1);
            LL t = u * ans / (r - l + 1);
            if(t^as[p]){
                update(ds[p],t,as[p]);
                as[p] = t;
            }
        }
        for(i = 1; i <= n; ++ i)printf_(as[i]);
    }
    return 0;
}

 

posted on 2012-09-17 13:06  aigoruan  阅读(175)  评论(0)    收藏  举报

导航