poj3468 線段樹 or splay

來源:互聯網
上載者:User

標籤:style   blog   color   os   io   資料   for   ar   

poj3468  裸線段樹。因為在熟悉splay 所以就用splay交了一發。。。開始用的scanf()!==2 居然TLE了。。。然後我就當單組測試資料做的 然後就過了  囧TZ  

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>using namespace std;#define rt ch[root][1]#define lrt ch[rt][0]#define ls ch[x][0]#define rs ch[x][1]#define inf 0x3f3f3f3fconst int maxn=100100;int root,top;//root為建立節點時的根節點int ch[maxn][2],f[maxn];long long sz[maxn],num[maxn],val[maxn],sum[maxn],add[maxn];int n,m;//ch[x][0],ch[x][1]:x的左右兒子,f[x]:x的父親節點,val[x]:x的值,sz[x]以x為根的子樹的節點個數inline void pushup(int x){    sz[x]=sz[ls]+sz[rs]+1;    sum[x]=sum[ls]+sum[rs]+val[x];    //維護其他資訊}inline void pushdown(int x){    if(add[x])    {        val[x]+=add[x];        add[ls]+=add[x];        add[rs]+=add[x];        sum[ls]+=(long long)(sz[ls]*add[x]);        sum[rs]+=(long long)(sz[rs]*add[x]);        add[x]=0;    }    //維護其他資訊}inline void link(int y,int x,int d)//把節點y的(左或右)兒子設為x{    f[x]=y;    ch[y][d]=x;}inline int is(int x)//判斷x為左兒子0還是右兒子1{    return ch[f[x]][1]==x;}inline void rotate(int x,int d){    int y=f[x];    int z=f[y];    pushdown(y);    pushdown(x);    link(y,ch[x][d],!d);    if(z) link(z,x,is(y));    f[x]=z;    link(x,y,d);    pushup(y);}inline void zag(int x){    rotate(x,0);}inline void zig(int x){    rotate(x,1);}inline void splay(int x,int goal=0)//第二個元素沒有傳參就預設為0,splay到0即將該節點旋轉到根//將根為r的子樹調整到x的父節點為goal的位置{    pushdown(x);    while(f[x]!=goal)    {        int y=f[x];        int z=f[y];        if(z==goal)        {            rotate(x,!is(x));            break;        }        if(ch[z][0]==y)        {            if(ch[y][0]==x) zig(y),zig(x);            else zag(x),zig(x);        }        else        {            if(ch[y][1]==x) zag(y),zag(x);            else zig(x),zag(x);        }    }    if(goal==0) root=x;    pushup(x);}//splay操作一般不做改動inline void newnode(int &x,int father,long long v){    x=++top;    f[x]=father;    val[x]=v;    add[x]=0;    ls=rs=0;    sz[x]=0;    //.....按題意建立資訊}inline bool insert(int v){    int x=root;    while(ch[x][val[x]<v])    {        if(val[x]==v)        {            splay(x);            return false;        }        x=ch[x][val[x]<v];    }    newnode(ch[x][val[x]<v],x,v);    splay(ch[x][val[x]<v]);    return true;}inline void build(int &x,int y,int l,int r){    if(l>r) return ;    int mid=(l+r)>>1;    newnode(x,y,num[mid]);    build(ls,x,l,mid-1);    build(rs,x,mid+1,r);    pushup(x);}inline void init(int n){    root=top=0;    ch[0][0]=ch[0][1]=f[0]=val[0]=add[0]=sz[0]=sum[0]=0;    newnode(root,0,0);    newnode(rt,root,0);    sz[root]=2;    for(int i=0; i<n; i++) scanf("%lld",&num[i]);    build(lrt,rt,0,n-1);    pushup(rt);    pushup(root);    //for(int x=0;x<=top;x++){    //    printf("x=%d f[x]=%d ls=%d rs=%d val=%d sum=%d add=%d sz=%d\n",x,f[x],ls,rs,val[x],sum[x],add[x],sz[x]);    //}}inline int pre(int x)//獲得前驅,調用時pre(root)即可{    x=ls;    if(x==0) return inf;    while(rs) x=rs;    return val[x];}inline int next(int x)//調用時next(root)即可,後繼{    x=rs;    if(x==0) return inf;    while(ls) x=ls;    return val[x];}inline int get_k(int x,int k)//返回的是第k小的點的標號(從小到大),值要用val來擷取{    pushdown(x);    int num=sz[ls]+1;    if(num==k) return x;    if(k<num) return get_k(ls,k);    return get_k(rs,k-num);}inline void update(){    int l,r;    long long c;    scanf("%d %d %lld",&l,&r,&c);    int x=get_k(root,l);    splay(x);    int y=get_k(root,r+2);    splay(y,root);    add[lrt]+=c;    sum[lrt]+=sz[lrt]*c;}//查詢一段區間的值inline void query(){    int l,r;    scanf("%d%d",&l,&r);    int x,y;    x=get_k(root,l);    y=get_k(root,r+2);    splay(x);    splay(y,root);    printf("%lld\n",sum[lrt]);}int main(){    scanf("%d%d",&n,&m);    init(n);    for(int i=1;i<=m;i++){        int l,r,d;        char c;        scanf("%c%c",&c,&c);        if(c==‘Q‘){            //cout<<c<<endl;            query();        }        if(c==‘C‘){            update();        }    }}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.