zoukankan      html  css  js  c++  java
  • SCOI2013 多项式的运算

    ---恢复内容开始---

    又是一道裸数据结构题。

    之前受序列操作的蛋疼写法影响,只用一个tag,不知道怎么记,之后看了下别人的,终于领悟要用两个tag,一个add,一个mul,维护相当简单,想清楚就行。

    简单说下解法。

    add mul就是一般的将[L,R]split出来然后打tag.

    mulx:我将[L,R+1]split出来,然后这一段split成l:[L,R-1],mid:[R,R],r[R+1,R+1],然后把mid的系数加到r上,把mid的系数赋为0,然后merge(mid,l,r);这里注意如果L==R将会出现问题,于是这里我特判了一下。

    还是就是见乘就得加long long.....

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 using namespace std;
      7 const int Maxn=100000+10,Mod=20130426,MaxR=100001;
      8 int _a[Maxn],cnt;
      9 inline void fadd(int&a,int b){
     10     a+=b;if(a>Mod)a-=Mod;
     11 }
     12 struct node{
     13     int v,sz,add,mul;//itself isn't in it
     14     node*ch[2];
     15     node(){
     16         sz=v=add=0;mul=1;
     17     }
     18     inline void maintain(){
     19         sz=ch[0]->sz+ch[1]->sz+1;
     20     }
     21     inline int cmp(int k){
     22         if(ch[0]->sz+1==k)return -1;
     23         return k>ch[0]->sz+1;
     24     }
     25     inline void AddTag(int Add,int Mul){
     26         v=(long long)v*Mul%Mod;
     27         fadd(v,Add);
     28         mul=(long long)mul*Mul%Mod;//注意long long 
     29         add=(long long)add*Mul%Mod;//注意long long 
     30         fadd(add,Add);
     31     }
     32     inline void down(){
     33         ch[0]->AddTag(add,mul);
     34         ch[1]->AddTag(add,mul);
     35         add=0;mul=1;
     36     }
     37 }da[Maxn],*root,*null;int tot;
     38 inline void rotate(node*&o,int d){
     39     node*t=o->ch[d];
     40     o->ch[d]=t->ch[d^1];
     41     t->ch[d^1]=o;
     42     o->maintain();
     43     (o=t)->maintain();
     44 }
     45 void splay(node*&o,int k){
     46     o->down();
     47     int d=o->cmp(k);
     48     if(d==-1)return;
     49     if(d)k-=o->ch[0]->sz+1;
     50     node*&p=o->ch[d];
     51     p->down();
     52     int d2=p->cmp(k);
     53     if(d2!=-1){
     54         if(d2)k-=p->ch[0]->sz+1;
     55         splay(p->ch[d2],k);
     56         if(d2!=d)rotate(p,d2);
     57         else rotate(o,d);
     58     }
     59     rotate(o,d);
     60 }
     61 void build(node*&o,int l,int r){
     62     if(l>r){
     63         o=null;
     64         return;
     65     }
     66     int mid=(l+r)>>1;
     67     o=da+ ++tot;
     68     build(o->ch[0],l,mid-1);
     69     build(o->ch[1],mid+1,r);
     70     o->maintain();
     71 }
     72 void print(node*o){
     73     if(o==null)return;
     74     o->down();
     75     print(o->ch[0]);
     76     ++cnt;
     77     if(cnt>=2 && cnt<=MaxR+2)_a[cnt-2]=o->v;
     78 //    printf("%d
    ",o->v);
     79     print(o->ch[1]);
     80 }
     81 inline int calc(int x,const int*a){
     82     int ret=a[MaxR];
     83     for(int i=MaxR;i>=0;i--){
     84         ret=(long long)ret*x%Mod;
     85         fadd(ret,a[i]);
     86     }    
     87     return ret;
     88 }
     89 inline void split(node*o,int k,node*&l,node*&r){
     90     splay(o,k);
     91     r=o->ch[1];
     92     (l=o)->ch[1]=null;
     93     l->maintain();
     94 }
     95 inline node*merge(node*l,node*r){
     96     splay(l,l->sz);
     97     l->ch[1]=r;
     98     l->maintain();
     99     return l;
    100 }
    101 int get_tp(char *opt){
    102     if(opt[0]=='a')return 1;
    103     if(opt[0]=='m')return opt[3]?3:2;
    104     return 4;
    105 }
    106 int main(){
    107     freopen("polynomial.in","r",stdin);
    108     freopen("polynomial.out","w",stdout);
    109     
    110     int tp,L,R,V,n;
    111     null=da;
    112     null->ch[0]=null->ch[1]=null;
    113     build(root,1,MaxR+2);
    114     node*o,*l,*r,*mid;
    115     char opt[10]={0};
    116     for(scanf("%d
    ",&n);n--;){
    117         scanf("%s",opt);
    118         tp=get_tp(opt);
    119         if(tp<=2){
    120             scanf("%d%d%d",&L,&R,&V);V%=Mod;
    121             split(root,L+1,l,o);
    122             split(o,R-L+1,mid,r);
    123             if(tp==1)mid->AddTag(V,1);
    124             else mid->AddTag(0,V);
    125             root=merge(merge(l,mid),r);
    126         }
    127         else if(tp==3){
    128             scanf("%d%d",&L,&R);
    129             split(root,L+1,l,o);
    130             split(o,R-L+2,mid,r);
    131             if(R==L){//这里必须特判 
    132                 splay(mid,1);
    133                 mid->down();
    134                 mid->ch[1]->down();
    135                 fadd(mid->ch[1]->v,mid->v);
    136                 mid->v=0;
    137             }else{
    138                 node*_o,*_l,*_r,*_mid;
    139                 split(mid,mid->sz-2,_l,_o);
    140                 split(_o,1,_mid,_r);
    141                 _mid->down();
    142                 _r->down();
    143                 fadd(_r->v,_mid->v);
    144                 _mid->v=0;
    145                 mid=merge(merge(_mid,_l),_r);
    146             }
    147             root=merge(merge(l,mid),r);
    148         }
    149         else {
    150             scanf("%d",&V);V%=Mod;
    151             cnt=0;
    152             print(root);
    153             printf("%d
    ",calc(V,_a));
    154         }
    155     }
    156     
    157     return 0;
    158 }
  • 相关阅读:
    POJ 1066 Treasure Hunt (线段相交)
    玲珑杯 第4次 String cut(暴力字符串)
    POJ 2653 Pick-up sticks (线段相交)
    HDU 3535 AreYouBusy (混合背包)
    HDU 1712 ACboy needs your help(分组背包)
    HDU 1074 Doing Homework (状压dp)
    POJ 1635 Subway tree systems (树的最小表示法)
    HDU 汉诺塔系列
    HYSBZ 1500 维修数列(伸展树模板)
    photoshop 快速切图
  • 原文地址:https://www.cnblogs.com/showson/p/4291895.html
Copyright © 2011-2022 走看看