• BZOJ3323: [Scoi2013]多项式的运算


    题解: 直接splay就好了 这题最大的亮点是 区间平移 我们可以通过把r和r+1节点合并 然后在l-1加上一个节点实现

    #include <bits/stdc++.h>
    const int MAXN=3e5+10;
    const int inf=2e5+2;
    #define ll long long
    using namespace std;
    const int mod=20130426;
    int ch[MAXN][2],size[MAXN],pre[MAXN],rt,cnt;
    ll tag1[MAXN],tag2[MAXN],key[MAXN];//tag1 jia tag2 cheng
    void newnode(int &x,int y){
        x=++cnt;ch[x][0]=ch[x][1]=0;key[x]=0;size[x]=1;pre[x]=y;
        tag1[x]=0;tag2[x]=1;
    }
    void add(int r,int vul){
        if(!r)return ;
        vul%=mod;
        tag1[r]+=vul;key[r]+=vul;
        tag1[r]%=mod;key[r]%=mod;
    }
    void mul(int r,ll vul){
        if(!r)return ;
        vul%=mod;
        tag2[r]*=1LL*vul;tag2[r]%=mod;
        tag1[r]*=1LL*vul;tag1[r]%=mod;
        key[r]*=1LL*vul;key[r]%=mod;
    }
    void push(int x){
        if(tag2[x]!=1){
            mul(ch[x][0],tag2[x]);
            mul(ch[x][1],tag2[x]);
            tag2[x]=1;
        }
        if(tag1[x]!=0){
            add(ch[x][0],tag1[x]);
            add(ch[x][1],tag1[x]);
            tag1[x]=0;
        }
    }
    void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
    void P(int x){
        if(pre[x])P(pre[x]);
        push(x);
    }
    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);
    }
    void splay(int x,int goal){
        P(x);
        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)rt=x;
        up(x);
    }
    int find1(int x,int sz){
        push(rt);
        if(sz==size[ch[x][0]]+1)return x;
        else if(sz<=size[ch[x][0]])return find1(ch[x][0],sz);
        else return find1(ch[x][1],sz-size[ch[x][0]]-1);
        up(rt);
    }
    void Add(){
        int l,r,v;scanf("%d%d%d",&l,&r,&v);
        splay(find1(rt,l+1),0);splay(find1(rt,r+3),rt);
        add(ch[ch[rt][1]][0],v);
    }
    void Mul(){
        int l,r;ll v;scanf("%d%d%lld",&l,&r,&v);
        splay(find1(rt,l+1),0);splay(find1(rt,r+3),rt);
        mul(ch[ch[rt][1]][0],v);
    }
    void update(){
        int l,r;scanf("%d%d",&l,&r);
        splay(find1(rt,r+1),0);splay(find1(rt,r+3),rt);
        int t=ch[ch[rt][1]][0];ch[ch[rt][1]][0]=0;up(ch[rt][1]);up(rt);
        pre[t]=0;splay(find1(rt,r+2),0);key[rt]+=key[t];key[rt]%=mod;
        size[t]=1;tag1[t]=0;tag2[t]=1;key[t]=0;ch[t][0]=ch[t][1]=0;
        splay(find1(rt,l+1),0);splay(find1(rt,l+2),rt);
        ch[ch[rt][1]][0]=t;pre[t]=ch[rt][1];up(ch[rt][1]);up(rt);
    }
    int st[MAXN],tot;
    void dfs(int x){
        if(!x)return ;
        push(x);
        dfs(ch[x][0]);
        st[++tot]=key[x];
        dfs(ch[x][1]);
        up(x);
    }
    void querty(){
        ll v;scanf("%lld",&v);
        tot=0;ll ans=0;ll x=1;
        dfs(rt);
        for(int i=2;i<=tot;i++)ans=(ans+1LL*st[i]*x)%mod,x=x*v%mod;
        printf("%lld
    ",ans);
    }
    void built(int &x,int l,int r,int y){
        if(l>r)return ;
        int mid=(l+r)>>1;
        newnode(x,y);
        built(ch[x][0],l,mid-1,x);
        built(ch[x][1],mid+1,r,x);
        up(x);
    }
    void inte(){
        newnode(rt,0);newnode(ch[rt][1],rt);
        built(ch[ch[rt][1]][0],1,inf,ch[rt][1]);
        up(ch[rt][1]);up(rt);
    }
    char str[11];
    int main(){
        inte();
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            if(str[0]=='a')Add();
            else if(str[0]=='q')querty();
            else{
                int len=strlen(str);
                if(len==4)update();
                else Mul();
            }
        }
        return 0;
    }
    

    3323: [Scoi2013]多项式的运算

    Time Limit: 20 Sec  Memory Limit: 64 MB
    Submit: 456  Solved: 166
    [Submit][Status][Discuss]

    Description

    某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车。一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针。现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目。该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 * x^2 + ... ,这个多项式初始时对于所有i有ai = 0。
    操作者可以进行四种操作:
    1. 将x^L 到x^R 这些项的系数乘上某个定值v
    2. 将x^L 到x^R 这些项的系数加上某个定值v
     
    3. 将x^L 到x^R 这些项乘上x变量
    4. 将某个定值v代入多项式F(x),并输出代入后多项式的值,之后多项式还原为代入前的状况
    经过观察,项目组发现使用者的操作集中在前三种,第四种操作不会出现超过10次。mzry1992 负责这个项目的核心代码,你能帮他实现么。

    Input

    输入的第一行有一个整数n 代表操作的个数。
    接下来n 行,每行一个操作,格式如下:
    mul L R v 代表第一种操作
    add L R v 代表第二种操作
    mulx L R 代表第三种操作
    query v 代表第四种操作

    对于30% 的数据:N <= 5000,0 <= L <= R <= 5000,0 <= v <= 10^9
    另有20% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9,没有mulx 操作
    剩下的50% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9

    Output

    对于每个query 操作,输出对应的答案,结果可能较大,需要模上20130426。

    Sample Input

    6
    add 0 1 7
    query 1
    mul 0 1 7
    query 2
    mulx 0 1
    query 3

    Sample Output

    14
    147
    588
    Hint
    操作一之后,多项式为F(x) = 7x + 7。
    操作三之后,多项式为F(x) = 49x + 49。
    操作五之后,多项式为F(x) = 49x^2 + 49x。

    HINT

    应上传者要求,此系列试题不公开,如有异议,本站将删除之。

  • 相关阅读:
    基于NFS的PV动态供给(StorageClass)
    Helm学习笔记
    k8s日志收集方案
    okhttputils【 Android 一个改善的okHttp封装库】使用(三)
    PopupWindowMenuUtil【popupwindow样式菜单项列表】
    NewBuiltBottomSheetDialog【新建底部对话框】
    NormalDialogFragmentDemo【普通页面的DialogFragment】
    ArticleRemoveDelDialog【基于AlertDialog的回收删除对话框】
    ConfirmCancelBottomSheetDialog【确认取消底部对话框】
    Android-PickerView【仿iOS的PickerView控件,并封装了时间选择和选项选择这两种选择器】使用
  • 原文地址:https://www.cnblogs.com/wang9897/p/9492687.html
Copyright © 2020-2023  润新知