首页 > 其他分享 >[COCI2015-2016#4] ENDOR 题解

[COCI2015-2016#4] ENDOR 题解

时间:2023-10-16 19:57:16浏览次数:32  
标签:ch 颜色 int 题解 COCI2015 向右走 变色龙 ENDOR dr

[COCI2015-2016#4] ENDOR 题解

首先要发现一个很重要的性质,那就是两只变色龙碰撞后回头,等效于两只变色龙继续往前走,其中向右走的颜色不变,而向左走的要改变颜色。

那这样就有一种 \(O(n^2)\) 的做法:对于向右的变色龙,直接贡献答案;对于向左的变色龙,我们按照碰到的先后顺序枚举它前面所有向右走的变色龙,这样每只向右走的变色龙都会给当前的颜色贡献 \(\frac{1}{2}(d_{i+1} - d_i)\) 的路程,当然这里的 \(d\) 是相邻的两只向右走的变色龙。注意开头和结尾都要特殊处理。

然后我们发现 \(k\) 很小,而 \(d_{i+1} - d_i\) 仅与向右走的变色龙有关,这启示我们去按照模 \(k\) 意义上去记录贡献。我们约定后面所说的关于颜色的运算均为模 \(k\) 意义下的。具体地,我们设 \(w_i\),表示如果初始颜色为 \(0\),则当前的变色龙会给颜色 \(i\) 造成 \(w_i\) 的贡献。那对于颜色为 \(x\) 的变色龙,就会给颜色 \(x+i\) 造成 \(w_i\) 的贡献。

我们考虑维护这个 \(w_i\)。假设我们现在已经有 \(t\) 只向右走的变色龙,当加入一只新的向右走的变色龙 \(p\) 时,它的颜色会导致 \(w\) 数组集体平移,因为每个颜色都在模 \(k\) 意义下加了 \(c_p\)。所以 \(w'_{i+c_p} = w_i\),同时还会在 \(c_p\) 位置上新增 \(\frac{1}{2} (d_{t+1} - d_t)\) 的贡献。这样,每个向左走的变色龙就可以通过 \(k\) 次枚举统计答案了。还是注意开头和结尾的特殊处理,具体看代码。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;

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-48), ch = getchar();}
	return x * f;
}
struct xwx {
	int d, col, dir;
	bool operator < (const xwx &b) const {
		return d < b.d;
	}
} a[N];
int n, K, L;
int c[N];
double ans[50];
double w[50];
int sum;
int dr[N], totr, cr[N];//记录向右走的变色龙的信息

void change(int del) {
	double b[50];
	for(int i = 0; i<K; ++i) {
		b[(i+del)%K] = w[i];
	}
	for(int i = 0; i<K; ++i) {
		w[i] = b[i];
	}
}//平移数组
int main() {
	n = read(), K = read(), L = read();
	for(int i = 1; i<=n; ++i) {
		a[i].d = read(), a[i].col = read();
		char op[3];
		scanf("%s", op);
		if(op[0] == 'L') a[i].dir = 0;
		else a[i].dir = 1, ans[a[i].col]+=(L-a[i].d);
	}
	sort(a+1, a+n+1);
	for(int i = 1; i<=n; ++i) {
		c[i] = a[i].col;
	}//完全没有意义的一步(
	for(int i = 1; i<=n; ++i) {
		if(a[i].dir) {
			++totr;
			dr[totr] = a[i].d;
			cr[totr] = a[i].col;
			sum = (sum + a[i].col)%K;//用来确定颜色最后会变成什么
			if(totr > 1) {
				change(a[i].col);
				w[a[i].col]+=(0.5*(dr[totr] - dr[totr-1]));
			}	
			continue;
		}
//		dr[totr+1] = a[i].d;
//		for(int j = totr; j>=1; --j) {
//			ans[c[i]]+=(0.5*(dr[j+1] - dr[j]));
//			c[i] = (c[i] + cr[j])%K;
//		}
//		ans[c[i]]+=0.5*(a[i].d + dr[1]);//n^2做法

		for(int j = 0; j<K; ++j) {
			ans[(c[i]+j)%K]+=w[j];
		} 
		ans[c[i]]+=(0.5*(a[i].d - dr[totr]));//第一只遇到的向右走的变色龙
		ans[(c[i] + sum)%K]+=(0.5*(a[i].d + dr[1]));//走过最后一只变色龙后还要一直走到终点。
	}
	for(int i = 0; i<K; ++i) {
		printf("%.1lf\n", ans[i]);
	}
	return 0;
}

标签:ch,颜色,int,题解,COCI2015,向右走,变色龙,ENDOR,dr
From: https://www.cnblogs.com/frostwood/p/17768209.html

相关文章

  • 【题解】AtCoder-ARC167
    AtCoder-ARC167AToastsforBreakfastParty一定不会有空盘,问题转化成\(2m\)个数,其中\(2m-n\)个是\(0\),这样一定是最大值和最小值一起,次大值和次小值一起,以此类推。提交记录:Submission-AtCoderAtCoder-ARC167BProductofDivisors\(A^B=\prod_ip_i^{Bc_i}\),那么答案......
  • CF1119F Niyaz and Small Degrees 题解
    原题翻译首先\(O(n^2\logn)\)的dp是simple的,我们设\(dp_{i,0/1}\)表示以\(i\)为根,\(i\)到\(fa_i\)这条边删/不删的最小权值和。转移是一个非常trick的问题,只需要假设所有都选\(dp_{i,0}\),然后把所有儿子按照\(dp_{v,1}+w(u,v)-dp_{v,0}\)排序,选前\(d......
  • P9745 「KDOI-06-S」树上异或 题解
    P9745「KDOI-06-S」树上异或题解\(x_i=0\)这题一看就不是很可做,先考虑部分分。对于一条链的情况,我们可以枚举上一个断边的位置,然后转移。一看数据范围,估计和值域有关,所以考虑\(x_i=1\)的部分分,如果全部点权都是1,那么一种方案只有0和1两种取值,考虑这个状态设计:\(f......
  • [ARC167D] Good Permutation 题解
    题意对于一个长度为\(N\)的排列\(Q\),定义其为好的,当且仅当对于任意整数\(i\in\left[1,N\right]\),在进行若干次操作\(i\leftarrowQ_i\)后可以得到\(i=1\)。给定一个排列\(P\),定义一次操作为交换两个数。定义\(M\)为可以将\(P\)变为一个好的的排列的最小操......
  • 计算机网络的分组转发算法例题解析
    例题展示例题解决将题目中要求的ip地址与相对应的子网掩码进行二进制上面的相与即可,若是与目的ip地址一致,那么就直接跳转到其对应的那个接口;否则就直接跳转到默认接口;本题答案为R2;......
  • UVA1366 Martian Mining 题解
    这个题可以用动态规划解决。令\(sbe_{i,j}\)为第\(j\)列\(1\)至\(i\)个格子\(BE\)矿总和,令\(snw_{i,j}\)为第\(i\)行\(1\)至\(j\)个格子\(NEW\)矿总和。\(dp_{i,j,0}\)表示为以第(\(i\),\(j\))为右下角,第(\(i\),\(j\))号格子建立\(BE\)矿管道的最大采矿量。\(dp......
  • P8854 [POI2002] 超级马 题解
    这题其实就是搜索,不知道怎么评绿的。题意有一个大小无限的棋盘,有一只马,给定\(n\)种跳法,判断马是否能跳到棋盘所有点。题解搜索马是否可以跳到他上下左右的四个点,因为只要能跳到这四个点,就可以以这四个点为基础跳到其他所有的点。这里有一些细节需要处理:因为每次操作能是......
  • CF1873E Building an Aquarium 题解
    这题看到第一眼就是二分。单调性二分最关键的东西是单调性在哪。单调性是如果高度越高,需要的水就越多,高度越矮,要用的水越少。不难得出代码:check函数:intcheck(intmid){ intsum=0; for(inti=1;i<=n;i++){ sum+=max(0ll,mid-a[i]); } if(sum<=x)returnsum; elsere......
  • html2canvas 截图不全问题解决
    有个低代码平台项目,需求是要将canvas画布上的echarts图表等组件截图保存,如果是正常比例(也就是百分百比例)截图是正常的,但如果画布处于缩放状态进行截图的话就会因组件上的一些样式影响而导致截图不全。为了解决这一问题,在网上也查找了很多资料,终于找到解决办法,亲测有效。话不多说,......
  • 第二届“梦羽杯”题解
    前言特别鸣谢出(蒯)题人:CJYA原题:NOIP2008普及组T4《立体图》B原题:HAOI2007反素数C......