NC20435. [SHOI2016]随机序列
描述
输入描述
第一行包含 2 个正整数 N 和 Q,为数的个数和询问的个数。接下来一行 n 个非负整数,依次表示a1,a2...an在接下来 Q 行,其中第 ?? 行两个非负整数Ti 和Vi,表示要将 A ti 修改为 Vi。其中 1 ≤ Ti ≤ N。保证对于 1 ≤ J ≤ N, 1 ≤ i ≤ Q,都有 Aj,Vi ≤ 10^4。 N,Q ≤ 100000,本题仅有三组数据
输出描述
输出共 Q 行,其中第 i 行表示第 i 个询问之后所有可能表达式的和,对10^9 + 7 取模。
示例1
输入:
5 5 9384 887 2778 6916 7794 2 8336 5 493 3 1422 1 28 4 60
输出:
890543652 252923708 942282590 228728040 608998099
C++11(clang++ 3.9) 解法, 执行用时: 116ms, 内存消耗: 4200K, 提交时间: 2019-03-16 12:59:12
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long LL; const int N=100005; const int MOD=1000000007; int n,m,a[N],s[N],ny[N]; struct tree{int s,tag;}t[N*4]; set<int> se; 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; } void build(int d,int l,int r) { t[d].tag=1; if (l==r) {t[d].s=s[l];return;} int mid=(l+r)/2; build(d*2,l,mid);build(d*2+1,mid+1,r); t[d].s=(t[d*2].s+t[d*2+1].s)%MOD; } void pushdown(int d) { if (t[d].tag==1) return; int w=t[d].tag;t[d].tag=1; t[d*2].s=(LL)t[d*2].s*w%MOD;t[d*2].tag=(LL)t[d*2].tag*w%MOD; t[d*2+1].s=(LL)t[d*2+1].s*w%MOD;t[d*2+1].tag=(LL)t[d*2+1].tag*w%MOD; } void ins(int d,int l,int r,int x,int y,int z) { if (l<r) pushdown(d); if (l==x&&r==y) {t[d].s=(LL)t[d].s*z%MOD;t[d].tag=(LL)t[d].tag*z%MOD;return;} int mid=(l+r)/2; if (y<=mid) ins(d*2,l,mid,x,y,z); else if (x>mid) ins(d*2+1,mid+1,r,x,y,z); else ins(d*2,l,mid,x,mid,z),ins(d*2+1,mid+1,r,mid+1,y,z); t[d].s=(t[d*2].s+t[d*2+1].s)%MOD; } int query(int d,int l,int r,int x,int y) { if (l<r) pushdown(d); if (l==x&&r==y) return t[d].s; int mid=(l+r)/2; if (y<=mid) return query(d*2,l,mid,x,y); else if (x>mid) return query(d*2+1,mid+1,r,x,y); else return (query(d*2,l,mid,x,mid)+query(d*2+1,mid+1,r,mid+1,y))%MOD; } int main() { ny[0]=ny[1]=1; for (int i=2;i<=10000;i++) ny[i]=(LL)(MOD-MOD/i)*ny[MOD%i]%MOD; n=read();m=read();s[0]=2; for (int i=0;i<n-1;i++) s[0]=(LL)s[0]*3%MOD; for (int i=1;i<=n;i++) { a[i]=read(); s[i]=(LL)s[i-1]*(a[i]?a[i]:1)%MOD*ny[3]%MOD; if (!a[i]) se.insert(i); } s[n]=(LL)s[n]*3%MOD*ny[2]%MOD; build(1,1,n); while (m--) { int x=read(),y=read(); if (!a[x]) se.erase(x); else ins(1,1,n,x,n,ny[a[x]]); a[x]=y; if (!a[x]) se.insert(x); else ins(1,1,n,x,n,a[x]); int p; if (!se.size()) p=n; else p=*se.begin()-1; printf("%d\n",query(1,1,n,1,p)); } return 0; }