洛谷 [COCI2015-2016#1] RELATIVNOST

PS:如果读过题了可以跳过题目描述直接到题解部分
提交链接:洛谷 [COCI2015-2016#1] RELATIVNOST

题目

题目描述

您是一位计数大师,有一天您的朋友 Luka 出了一道问题来刁难您。

Luka 是一位勤劳的画家,他的画很好,所以会有 n n n 个人来买他的画。

画分两种,黑白画与彩色画。

Luka 十分勤劳,所以他有无穷多的画。

Luka 讨厌出售黑白画,所以他希望至少有 c c c 个人会买走一张彩色画。

i i i 个人会至多购买 a i a_i ai 张彩色画, b i b_i bi 张黑白画,且它们会至少购买一幅画。

但是,客户们只能单独购买彩色画或黑白画。

客户们会不断改变 a i a_i ai b i b_i bi,这种改变会持续 q q q 次。

客户以 1 ∼ n 1\sim n 1n 编号。

您需要求出在每次改变之后,Luka 会有几种方案满足所有需求。

为了防止输出太大,Luka 只需要您告诉他方案数   m o d     1 0 4 + 7 \bmod\ 10^4+7 mod 104+7 的值。

输入格式

第一行为两个整数 n , c n,c n,c

第二行为 n n n 个整数 a i a_i ai

第三行为 n n n 个整数 b i b_i bi

第四行为一个整数 q q q

接下来 q q q 行,一行三个整数 p i , a p i , b p i p_i,a_{p_i},b_{p_i} pi,api,bpi,第 i i i 行表示标号 p i p_i pi 的顾客将 a i a_i ai b i b_i bi 更换成 a p i a_{p_i} api b p i b_{p_i} bpi

输出格式

q q q 行,一行一个整数,第 i i i 行的值表示进行了第 i i i 次改变后,满足条件的方案数   m o d     1 0 4 + 7 \bmod\ 10^4+7 mod 104+7 的值。

样例 #1

样例输入 #1

2 2
1 1
1 1
1
1 1 1

样例输出 #1

1

样例 #2

样例输入 #2

2 2
1 2
2 3
2
1 2 2
2 2 2

样例输出 #2

4
4

样例 #3

样例输入 #3

4 2
1 2 3 4
1 2 3 4
1
4 1 1

样例输出 #3

66

提示

样例 1 说明

第一次改变后,我们只有唯一的一种方案,就是向两位用户都出售一张彩色画。

数据范围及限制
  • 对于 30 % 30\% 30% 的数据,保证 n , q ≤ 1 0 3 n,q\le 10^3 n,q103
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n , q ≤ 1 0 5 1\le n,q\le 10^5 1n,q105 1 ≤ c ≤ 20 1\le c\le 20 1c20 1 ≤ a i , b i , a p i , b p i ≤ 1 0 9 1\le a_i,b_i,a_{p_i},b_{p_i}\le 10^9 1ai,bi,api,bpi109 1 ≤ p i ≤ n 1\le p_i\le n 1pin
说明

本题满分 140 140 140 分。

本题译自 Croatian Open Competition in Informatics 2015/2016 Contest #1 T5 RELATIVNOST。

题解

dp+线段树优化

注意为了节约内存,我们需要把线段树的 l l l r r r省略掉,用位运算来查找。


2022.10.26
因为有人受我题解写得太水的影响,专门绕过一个人走过来问我,所以我决定补充一下题解。

线段树

对于线段树的每个节点,保存的是第 l l l r r r个人的信息,我们先不管它存的是什么信息,反正指到这个节点,就是说的这些人。
线段树
比如我们看到上图这个线段树,红色的数字表示节点编号,黑色的数字就表示该节点存的人的信息。

然后问题就来了,节点里面到底存的这些人的什么信息呢?

这当然就要说到dp的定义了。

dp方程

我们定义 d p i , j dp_{i,j} dpi,j表示 i i i号节点中买 j j j张彩色画的情况数。

注意如果买画的张数多于 c c c张我们都把它的情况数计入 d p i , c dp_{i,c} dpi,c

转移方程当然是用乘法原理直接两层循环用两个子节点更新父节点啦。

想必做到这道题的人代码阅读能力都不弱,具体的方程就自己详见 u p d a t e update update函数内部吧。


代码实现

140pts

提醒一下,洛谷上要想过一定要开O2优化!!!!!

//洛谷 [COCI2015-2016#1] RELATIVNOST
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
using namespace std;
const int mo=10007;
int n,c;
int a[100010];
int b[100010];
int q;
int p,ap,bp;
short t[400010][21];

void in(int &x){
	int nt;
	x=0;
	while(!isdigit(nt=getchar()));
	x=nt^'0';
	while(isdigit(nt=getchar())){
		x=(x<<3)+(x<<1)+(nt^'0');
	}
}

void out(register int x){
	if(x>9) out(x/10ll);
	putchar(x%10ll^48ll);
}

void update(int x){
	for(int i=0;i<=c;++i){
		t[x][i]=0;
	}
	for(int i=0;i<=c;++i){
		for(int j=0;j<=c;++j){
			t[x][min(i+j,c)]+=(1ll*t[x<<1][i]*t[x<<1|1][j])%mo;
			t[x][min(i+j,c)]%=mo;
		}
	}
}

void build(int x,int l,int r){
	if(l==r){
		t[x][1]=a[l];
		t[x][0]=b[l];
		return;
	}
	int mid=l+r>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	update(x);
}

void change(int x,int l,int r,int p,int pa,int pb){
	if(l==r){
		t[x][1]=pa;
		t[x][0]=pb;
		return;
	}
	int mid=l+r>>1;
	if(p<=mid){
		change(x<<1,l,mid,p,pa,pb);
	}
	else{
		change(x<<1|1,mid+1,r,p,pa,pb);
	}
	update(x);
}

int main(){
	register int i,j;
	in(n),in(c);
	for(i=1;i<=n;++i){
		in(a[i]);
		a[i]%=mo;
	}
	for(i=1;i<=n;++i){
		in(b[i]);
		b[i]%=mo;
	}
	build(1,1,n);
	in(q);
	for(i=1;i<=q;++i){
		in(p),in(ap),in(bp);
		ap%=mo;
		bp%=mo;
		change(1,1,n,p,ap,bp);
		out(t[1][c]);
		putchar('\n');
	}
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月半流苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值