bzoj4597 [Shoi2016]随机序列
来源:互联网 发布:大数据的工资待遇 编辑:程序博客网 时间:2024/05/22 05:34
【题意】
n个数,任意相邻两数之间加入“+”“-”“*”三种符号中的一种,数列的答案即为这3^(n-1)种表达式的和mod(10^9+7)的值。
m次修改,每次修改一个数并求出数列的答案。
【数据范围】
n<=100000,m<=100000,1<=数列中的数<=10000
【思路】
设w=10000。
定义一个区间[L,R]中的符号均为“*”,且L前与R后的符号不为“*”。
由于“+”“-”可相互抵消,对于所有L>=2的区间,L前面的符号不为“*”(定义),“+”“-”次数相同,故这样的区间对答案贡献为0。
故答案由若干L=1的区间计算得到:
若L=1且R=n,后面没有符号位,故它对答案贡献1次。
若L=1且R<n,后面的符号任意填,故共有2*3^(n-R-1)种填法,贡献2*3^(n-R-1)次。
每次修改相当于一个后缀区间/原数*现数,/原数相当于*原数的逆元,逆元可预处理得到。故问题变为维护区间修改(乘一个数),整体求和,裸线段树。
【时间复杂度】
O((n+m) log n+w log (10^9+7))
#include<cstdio>#include<cstring>#include<algorithm>#define N 100010#define ll long long#define mod 1000000007using namespace std; struct tt{int a, b, l, r, s, f;}t[N*2];int n, m, w[N], bin[N], v[N], now, l, inv[N], x, y, z; inline int read(){ int x=0, f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;} int pow(int y, int x){ int s=1, t=y; while(x){ if(x&1)s=(ll)s*t%mod; t=(ll)t*t%mod; x>>=1; } return s;} void update(int i){ t[i].s=(t[t[i].l].s+t[t[i].r].s)%mod;}void maketree(int L, int R){ t[l].a=L; t[l].b=R; t[l].l=t[l].r=t[l].s=0; t[l].f=1; if(L<R){ int mid=(L+R)>>1, l1=l; l++; t[l1].l=l; maketree(L, mid); l++; t[l1].r=l; maketree(mid+1, R); update(l1); }else t[l].s=v[L];}void pushdown(int i){ if(t[i].f>1){ t[t[i].l].f=(ll)t[t[i].l].f*t[i].f%mod; t[t[i].l].s=(ll)t[t[i].l].s*t[i].f%mod; t[t[i].r].f=(ll)t[t[i].r].f*t[i].f%mod; t[t[i].r].s=(ll)t[t[i].r].s*t[i].f%mod; t[i].f=1; }}void ins(int i, int a, int b, int c){ if(a<=t[i].a&&t[i].b<=b){ t[i].f=(ll)t[i].f*c%mod; t[i].s=(ll)t[i].s*c%mod; return; } pushdown(i); int mid=(t[i].a+t[i].b)>>1; if(a<=mid)ins(t[i].l, a, b, c); if(mid<b)ins(t[i].r, a, b, c); update(i);} int main(){ n=read(); m=read(); for(int i=1; i<=n; i++)w[i]=read(); bin[0]=2; for(int i=1; i<=n; i++)bin[i]=(ll)bin[i-1]*3%mod; for(int i=0; i<=10000; i++)inv[i]=pow(i, mod-2); now=1; for(int i=1; i<=n; i++){ now=(ll)now*w[i]%mod; if(i<=n-1)v[i]=(ll)now*bin[n-i-1]%mod; else v[i]=now; } l=1; maketree(1, n); for(int i=1; i<=m; i++){ x=read(); y=read(); z=(ll)inv[w[x]]*y%mod; w[x]=y; ins(1, x, n, z); printf("%d\n", t[1].s); } return 0;}
0 0
- BZOJ4597 [Shoi2016]随机序列
- bzoj4597 [Shoi2016]随机序列
- BZOJ4597: [Shoi2016]随机序列
- [bzoj4597/Shoi2016]随机序列
- 【bzoj4597】[Shoi2016]随机序列 线段树
- 【BZOJ4597】【Shoi2016】随机序列 线段树
- 【bzoj4597】【Shoi2016】【随机序列】【线段树】
- [bzoj4597][Shoi2016]随机序列 线段树
- [BZOJ4597][SHOI2016]随机序列(线段树)
- 4597: [Shoi2016]随机序列
- bzoj 4597: [Shoi2016]随机序列
- BZOJ 4597: [Shoi2016]随机序列
- C#生成随机序列
- 产生随机整数序列
- Android/Java随机序列
- 平稳随机序列
- python 随机数,随机序列
- 产生一个随机序列
- [10]全局属性和其他
- 1
- 知识库--ApplicationFilterConfig+FilterConfig实践(54)
- PHP中的curl函数
- 一些概念
- bzoj4597 [Shoi2016]随机序列
- 队列
- thinkphp5.0 在nginx下的配置
- android
- struts2图片上传并且显示(注意乱码)
- 实现主函数将年、月、日(结构体类型)传递给days函数,days函数计算该年该月该日是该年的第几天并传回主函数输
- Codeforces Round #386 (Div. 2) A+B+C+D!
- Exploit Development – 使用SEH绕过Security Cookie
- spring--filter如何注入 spring管理的bean(54)