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\n",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);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\n",calc(V,_a));
154         }
155     }
156
157     return 0;
158 }
时间: 2024-09-30 04:45:35

SCOI2013 多项式的运算的相关文章

bzoj 3323: [Scoi2013]多项式的运算.

3323: [Scoi2013]多项式的运算 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 412  Solved: 148[Submit][Status][Discuss] Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) =

SCOI2013 多项式的运算 (BZOJ 3323)

似乎仍然不能附传送门..权限题T_T... 3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec  Memory Limit: 64 MB Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 *

BZOJ3323: [Scoi2013]多项式的运算

3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec  Memory Limit: 64 MBSubmit: 128  Solved: 33[Submit][Status] Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0

多项式相加运算

 多项式相加运算,使用链表实现,代码仍需要改善,这里先初步做个记录 //实现多项式的表示及相加 by Denis #include <stdio.h> #include <malloc.h> #define ture 1 #define false 0 typedef int ElemType; typedef struct LNode{ ElemType coef; //系数 int expn; //指数 struct LNode *next; }polynomia; pol

多项式加法运算 使用链表实现

/* 多项式加法运算 使用链表实现 */ #include <iostream> using namespace std; //使用不带头结点的单向链表,按照指数递减的顺序排列 typedef struct PolyNode { int coef; //系数 int expon; //指数 PolyNode *link; //指向下一个节点的指针 }*polynomial, npolynomial; polynomial PolyAdd(polynomial p1, polynomial p2

Calculation Of Polynomial(多项式的运算) C++

本文实现了一个多项式的类,类中重载了多项式的加法.减法.乘法,并且对>> 和 << 进行了重载. 其中多项式的输入(输出)格式为: K  N1 aN1 N2 aN2 ... NK aNK 其中K表示多项式的系数,NK表示第K项的系数aNk相应的系数,并且多项式的系数递减的序列. 1 //polynomial.h 2 #include <iostream> 3 #include <vector> 4 #include <iomanip> 5 6 c

一元稀疏多项式加法运算

描述: 设计一个一元稀疏多项式加法运算器,完成多项式a和b相加,建立多项式a+b. 输入说明: 一组输入数据,所有数据均为整数.第1行为2个正整数n,m,其中 n表示第一个多项式的项数,m表示第二个多项式的项数:第2行包含2n个整数,每两个整数分别表示第一个多项式每一项的系数和指数:第3行包含2m个整数,每两个整数分别表示第二个多项式每一项的系数和指数.(注:序列按指数升序排列) 输出说明: 在一行以类多项式形式输出结果,指数按从低到高的顺序.注意,系数值为1的非零次项的输出形式中略去系数1,如

单链表实现多项式的表示及运算

单链表实现多项式的加法运算 最近学习数据结构的线性表,有顺序存储和链表两种,多项式的表示和运算,最能巩固学习成果,现在提供详细代码,来实现多项式的加法运算. 多项式用单链表最为合适,不会造成更多的资源浪费. 如果你恰好用的这本书--数据结构(Java版)(第4版)(叶核亚),推荐你去下面这个链接下载书本源代码,将更助你学的轻松. http://download.csdn.net/detail/wang______jing/9907538 1 //单链表类,实现一些基本单链表的操作 2 publi

一元多项式的运算

以一元多项式加法运算为例: A,B可用线性链表可以表示为: “和多项式”链表如下(图中的长方框表示已经被释放的结点): #include <stdio.h> #include <stdlib.h> typedef struct Polyn{ int data; int index; struct Polyn *next; }Polyn,*Polynlist; void CreatPolyn(Polynlist &p,int m)//输入m项的系数和指数,建立一元多项式P {