日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[SCOI2013]多项式的运算

發布時間:2024/4/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [SCOI2013]多项式的运算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

嘟嘟嘟

半年不寫splay,一寫就半年……
辛虧我長精神頭復習了一下,要不然考場上遇到平衡樹的題肯定廢了。

這道題,無非就讓你求這么幾個事兒:
1.區間加。
2.區間乘。
3.區間向后移一位。
4.代數求和。

對于查詢操作,因為最多不超過10次,所以單次\(O(nlogn)\)暴力就好了。

前兩個操作不說了。

對于第三個操作,要動一點腦子:相當于把第\(L\)位清零,\([L + 1, R - 1]\)向右移一位,最后第\(R + 1\)位加上第\(R\)位的值。
于是我一直在想,怎么實現區間平移的操作。后來發現只要在\(L\)之前插入一個權值為0的節點就完事了,同時處理了清零和平移一位的操作。
然后就是單點加和刪除節點了。
不過第三個操作整體很坑。細節比較麻煩:插入完節點后,第\(R\)位就變成了第\(R + 1\)位,所以應該刪的是\(R + 1\),不是\(R\)
代碼中懶得寫垃圾回收了,索性開了二倍的空間。
然后因為沒有告訴最高次項,所以又開了個變量Max維護最高次。

#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> #include<cctype> #include<vector> #include<stack> #include<queue> using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define In inline typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 1e5 + 5; const ll mod = 20130426; inline ll read() {ll ans = 0;char ch = getchar(), last = ' ';while(!isdigit(ch)) last = ch, ch = getchar();while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();if(last == '-') ans = -ans;return ans; } inline void write(ll x) {if(x < 0) x = -x, putchar('-');if(x >= 10) write(x / 10);putchar(x % 10 + '0'); }char s[10]; int n, Max = 0; struct Tree {int ch[2], fa, siz;ll val, add, mul; }t[maxn << 1]; int root, tcnt = 0;In ll mul(ll a, ll b) {return a * b % mod;} In ll inc(ll a, ll b) {return a + b >= mod ? a + b - mod : a + b;}In ll quickpow(ll a, ll b) {ll ret = 1;for(; b; b >>= 1, a = a * a % mod)if(b & 1) ret = ret * a % mod;return ret; }In void c_mul(int now, ll d) {t[now].val = mul(t[now].val, d);t[now].mul = mul(t[now].mul, d); t[now].add = mul(t[now].add, d); } In void c_add(int now, ll d) {t[now].val = inc(t[now].val, d);t[now].add = inc(t[now].add, d); } In void pushdown(int now) {if(t[now].mul ^ 1){if(t[now].ch[0]) c_mul(t[now].ch[0], t[now].mul);if(t[now].ch[1]) c_mul(t[now].ch[1], t[now].mul);t[now].mul = 1;}if(t[now].add){if(t[now].ch[0]) c_add(t[now].ch[0], t[now].add);if(t[now].ch[1]) c_add(t[now].ch[1], t[now].add);t[now].add = 0; } } In void pushup(int now) {t[now].siz = t[t[now].ch[0]].siz + t[t[now].ch[1]].siz + 1; } In void rotate(int x) {int y = t[x].fa, z = t[y].fa, k = (t[y].ch[1] == x);t[z].ch[t[z].ch[1] == y] = x, t[x].fa = z;t[y].ch[k] = t[x].ch[k ^ 1], t[t[y].ch[k]].fa = y;t[x].ch[k ^ 1] = y, t[y].fa = x;pushup(y), pushup(x); } In void splay(int x, int s) {while(t[x].fa ^ s){int y = t[x].fa, z = t[y].fa;if(z ^ s) rotate(((t[y].ch[0] == x) ^ (t[z].ch[0] == y)) ? x : y);rotate(x);}if(!s) root = x; }In void _PrintTr(int now) { if(!now) return;pushdown(now);printf("now:%d val:%lld ls:%d rs:%d\n", now, t[now].val, t[now].ch[0], t[now].ch[1]);_PrintTr(t[now].ch[0]), _PrintTr(t[now].ch[1]); }In int build(int L, int R, int _f) {if(L > R) return 0;int mid = (L + R) >> 1, now = ++tcnt;if(_f) t[now].fa = _f;t[now].siz = 1;t[now].val = (mid == 1 || mid == maxn - 2) ? -INF : 0;t[now].add = 0, t[now].mul = 1;t[now].ch[0] = build(L, mid - 1, now);t[now].ch[1] = build(mid + 1, R, now);pushup(now);return now; }In int find(int k) {int now = root;while("ACAC!"){pushdown(now);if(t[t[now].ch[0]].siz >= k) now = t[now].ch[0];else if(t[t[now].ch[0]].siz + 1 == k) return now;else k -= (t[t[now].ch[0]].siz + 1), now = t[now].ch[1];} } In void split(int L, int R) {int a = find(L), b = find(R + 2);splay(a, 0), splay(b, a);pushdown(root), pushdown(t[root].ch[1]); }In void change(int L, int R) {int a = find(L), b = find(L + 1);splay(a, 0), splay(b, a);pushdown(root), pushdown(t[root].ch[1]);int now = t[root].ch[1], p = ++tcnt;t[now].ch[0] = p;t[p].fa = now, t[p].siz = 1;t[p].add = t[p].val = 0, t[p].mul = 1;splay(p, 0);split(R + 1, R + 1);now = t[root].ch[1], p = t[now].ch[0];t[now].val = inc(t[now].val, t[p].val);--t[now].siz;t[now].ch[0] = 0, t[p].fa = 0;splay(now, 0); }In ll query(int x) {int a = find(x + 1); splay(a, 0);return t[root].val; }int main() {// freopen("ha.in", "r", stdin);// freopen("ha.out", "w", stdout);n = read();root = build(1, maxn - 2, 0);for(int i = 1; i <= n; ++i){scanf("%s", s);if(s[3] == 'x'){int L = read() + 1, R = read() + 1;change(L, R);Max = max(Max, R + 1);}else if(s[0] == 'a'){int L = read() + 1, R = read() + 1, d = read();Max = max(Max, R);split(L, R), c_add(t[t[root].ch[1]].ch[0], d);}else if(s[0] == 'm'){int L = read() + 1, R = read() + 1, d = read();Max = max(Max, R);split(L, R), c_mul(t[t[root].ch[1]].ch[0], d);}else{ll d = read(), ans = 0;for(int j = 1; j <= Max; ++j)ans = inc(ans, mul(query(j), quickpow(d, j - 1)));write(ans), enter;}}return 0; }

轉載于:https://www.cnblogs.com/mrclr/p/10479094.html

總結

以上是生活随笔為你收集整理的[SCOI2013]多项式的运算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。