• Bzoj2762: [JLOI2011]不等式组


    题解:很明显 要对a分类考虑 对于a的符号建两颗平衡树 对于每次查询前驱节点和后继结点 然后维护size即可

    /**************************************************************
        Problem: 2762
        User: c20161007
        Language: C++
        Result: Accepted
        Time:1476 ms
        Memory:4920 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define ll long long
    const int MAXN=1e5+10;
    const ll inf=1e9+10;
    using namespace std;
    int vis[MAXN],cnt1;
    typedef struct node{
        ll a,b;
    }node;
    int size[MAXN],ch[MAXN][2],pre[MAXN],cnt;
    bool aim[MAXN];
    node d[MAXN];
    void Treavel(int x)
    {
        if(x)
        {
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,分子=%2d,分母=%2d
    ",x,ch[x][0],ch[x][1],pre[x],size[x],d[x].a,d[x].b);
            Treavel(ch[x][1]);
        }
    }
    void debug(int rp)
    {
        printf("root:%d
    ",rp);
        Treavel(rp);
    }
    typedef struct Splay{
        int root;ll minn;int pos;
        void newnode(int &x,ll t1,ll t2,int fa){
        x=++cnt;size[x]=1;ch[x][0]=ch[x][1]=0;pre[x]=fa;
        d[x].a=t1;d[x].b=t2;
        }
        void inte(){
        newnode(root,-1*inf,1,0);
        newnode(ch[root][1],inf,1,root);
        }
        void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;return ;}
        void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
        if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);up(x);
        }
        void splay(int x,int goal){
        while(pre[x]!=goal){
            if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x);
            else{
            int y=pre[x];int kind=ch[pre[y]][0]==y;
            if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
            else rotate(y,kind),rotate(x,kind);
            }
        }
        if(goal==0)root=x;
        up(x);
        }
        void insert(int &x,ll a,ll b,int fa){
        if(!x){newnode(x,a,b,fa);return ;}
        if(d[x].a*b<=d[x].b*a)insert(ch[x][1],a,b,x);
        else insert(ch[x][0],a,b,x);
        up(x);
        }
        void Add(ll t1,ll t2){
        insert(root,t1,t2,0);vis[cnt1]=cnt;
        splay(cnt,0);
        }
        int find1(int x,int sz){
        if(size[ch[x][0]]+1==sz)return x;
        else if(size[ch[x][0]]>=sz)return find1(ch[x][0],sz);
        else return find1(ch[x][1],sz-size[ch[x][0]]-1);
        }
        void Del(int pos){
        if(vis[pos]<=0)return ;
        int t1=vis[pos];splay(t1,0);
        int lsz=size[ch[root][0]];int rsz=lsz+2;
        splay(find1(root,lsz),0);splay(find1(root,rsz),root);
        ch[ch[root][1]][0]=0;up(ch[root][1]);up(root);
        vis[pos]=0;
        }
        void find2(int x,ll k){
        if(!x)return ;
        if(d[x].a>=d[x].b*k)pos=x,find2(ch[x][0],k);
        else find2(ch[x][1],k);
        }
        void find3(int x,ll k){
        if(!x)return ;
        if(d[x].a<=d[x].b*k)pos=x,find3(ch[x][1],k);
        else find3(ch[x][0],k);
        }
        int querty1(ll k){
        find2(root,k);splay(pos,0);return size[ch[root][0]]-1;
        }
        int querty2(ll k){
        find3(root,k);splay(pos,0);return size[ch[root][1]]-1;
        }
    }Splay;
    int main(){
        int n;scanf("%d",&n);
        Splay T1,T2;T1.inte();T2.inte();
        char str[10];ll a,b,c;int ans1=0;
        for(int i=1;i<=n;i++){
        scanf(" %s",str);
        if(str[0]=='A'){
            cnt1++;
            scanf("%lld%lld%lld",&a,&b,&c);
            if(a==0){
            vis[cnt1]=-1;
            if(c<b)ans1++,vis[cnt1]=-2;
            }
            else if(a<0){
            ll t1=c-b;ll t2=__gcd(t1,a);a/=t2;t1/=t2;
            if(a<0)t1*=-1,a*=-1;
            T2.Add(t1,a);
            aim[cnt1]=1;
            }
            else{
            ll t1=c-b;ll t2=__gcd(t1,a);a/=t2;t1/=t2;
            if(a<0)t1*=-1,a*=-1;
            T1.Add(t1,a);
            aim[cnt1]=0;
            }
        }
        else if(str[0]=='D'){
            scanf("%lld",&a);
            if(vis[a]==-2)ans1--,vis[a]=0;
            if(vis[a]<0)vis[a]=0;
            if(vis[a]<=0)continue;
            if(aim[a])T2.Del(a);
            else T1.Del(a);
        }
        else{
            scanf("%lld",&a);
            ll ans=ans1;ans+=T1.querty1(a);ans+=T2.querty2(a);
            printf("%lld
    ",ans);
        }
    //  debug(T1.root);
    //  debug(T2.root);
        } 
    }
    

    2762: [JLOI2011]不等式组

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1198  Solved: 322
    [Submit][Status][Discuss]

    Description

    旺汪与旺喵最近在做一些不等式的练习。这些不等式都是形如ax+b>c 的一元不等式。当然,解这些不等式对旺汪来说太简单了,所以旺喵想挑战旺汪。旺喵给出一组一元不等式,并给出一个数值 。旺汪需要回答的是x=k 时成立的不等式的数量。聪明的旺汪每次都很快就给出了答案。你的任务是快速的验证旺汪的答案是不是正确的。
     

    Input

    输入第一行为一个正整数 ,代表接下来有N 行。
    接下来每一行可能有3种形式:
    1.“Add a b c”,表明要往不等式组添加一条不等式ax+b>c ;
    2.“Del i”,代表删除第i 条添加的不等式(最先添加的是第1条)。
    3.“Query k”,代表一个询问,即当x=k 时,在当前不等式组内成立的不等式的数量。
    注意一开始不等式组为空,a,b,c,i,k 均为整数,且保证所有操作均合法,不会出现要求删除尚未添加的不等式的情况。
     

    Output

     
    对于每一个询问“Query k”,输出一行,为一个整数,代表询问的答案。

    Sample Input

    9
    Add 1 1 1
    Add -2 4 3
    Query 0
    Del 1
    Query 0
    Del 2
    Query 0
    Add 8 9 100
    Query 10

    Sample Output

    1
    1
    0
    0

    HINT

    第1条添加到不等式组的不等式为x+1>1 ,第2条为-2x+4>3 ,所以第1个询问的时候只有第2条不等式可以成立,故输出1。

    然后删除第1条不等式,再询问的时候依然是只有第2条不等式可以成立,故输出1。

    再删除第2条不等式后,因为不等式组里面没有不等式了,所以没有不等式可以被满足,故输出0。

    继续加入第3条不等式8x+9>100 ,当x=k=10时有8*10+9=89<100,故也没有不等式可以被满足,依然输出0。

    数据范围:

    20%的数据, N<=1000;

    40%的数据, N<=10000;

    100%的数据,N<=100000,

    a,b,c的范围为[-10^8,10^8],k的范围为[-10^6,10^6]。

  • 相关阅读:
    vue cli
    vue element-ui
    vue mint-ui
    vue富文本编辑器
    vue-单文件组件相关
    axios
    vue Router
    css 行内元素和块级元素的一些注意事项
    golang协程和变量
    Internet地址介绍
  • 原文地址:https://www.cnblogs.com/wang9897/p/9179007.html
Copyright © 2020-2023  润新知