CF377D Developing Game [扫描线]

传送门

挺好的一道题...

我们考虑每一个点对哪一些答案有贡献

那么就是左端点在li-xi的区间, 右端点在xi-ri的区间有贡献

放到二维平面上, 就是一个矩形, 扫描线看什么时候最大就可以了


#include<bits/stdc++.h>
#define N 300050
using namespace std;
int read(){
	int cnt = 0; char ch = 0;
	while(!isdigit(ch)) ch = getchar();
	while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
	return cnt;
}
struct Node{
	int x,l,r,val;
	friend bool operator < (const Node &a,const Node &b){
		return a.x == b.x ? a.val < b.val : a.x < b.x;
	}
}a[N]; int tot; 
struct Pos{int l,x,r;}p[N];
struct Segmentree{ int Pos,val,tag;}t[N<<2];
int n,ans,L,R; 
void Pushup(int x){ 
	if(t[x<<1].val > t[x<<1|1].val){
		t[x].val = t[x<<1].val;
		t[x].Pos = t[x<<1].Pos;
	}
	else{
		t[x].val = t[x<<1|1].val;
		t[x].Pos = t[x<<1|1].Pos;
	}
}
void Pushdown(int x){
	if(t[x].tag){
		t[x<<1].val += t[x].tag; t[x<<1].tag += t[x].tag;
		t[x<<1|1].val += t[x].tag; t[x<<1|1].tag += t[x].tag;
		t[x].tag = 0;
	} 
}
void Build(int x,int l,int r){
	if(l==r){ t[x].Pos = l; return;}
	int mid = (l+r) >> 1; Build(x<<1,l,mid); Build(x<<1|1,mid+1,r);
	Pushup(x);
}
void Modify(int x,int l,int r,int L,int R,int v){
	if(L<=l && r<=R){ t[x].val += v, t[x].tag += v; return;}
	Pushdown(x); 
	int mid = (l+r) >> 1;
	if(L<=mid) Modify(x<<1, l, mid, L, R, v);
	if(R>mid) Modify(x<<1|1, mid+1, r, L, R, v);
	Pushup(x);
}
int main(){
	n = read(); Build(1,1,N-50);
	for(int i=1;i<=n;i++){
		int l = read(), x = read(), r = read();
		a[++tot] = (Node){l, x, r, 1};
		a[++tot] = (Node){x+1, x, r, -1};
		p[i] = (Pos){l,x,r};
	} sort(a+1, a+tot+1);
	for(int i=1;i<=tot;i++){
		Modify(1,1,N-50, a[i].l, a[i].r, a[i].val);
		if(t[1].val > ans){
			ans = t[1].val; L = a[i].x; R = t[1].Pos;
		}
	} printf("%d\n",ans); 
	for(int i=1;i<=n;i++)
		if(p[i].x >= L && p[i].x <= R && p[i].l<=L && p[i].r>=R)
			printf("%d ",i);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
非常抱歉,我犯了一个错误,上述示例代码并没有实现扫描线从左到右根据数据前进的效果。以下是一个更新后的示例代码,可以实现医疗波形图的扫描线效果: ```c #include <stdio.h> #include "GUI.h" #include "DIALOG.h" #define XSIZE 320 // 波形图宽度 #define YSIZE 200 // 波形图高度 #define YOFFSET 20 // 波形图上边距 #define YDIVS 10 // 波形图纵向刻度数 #define XDIVS 10 // 波形图横向刻度数 #define XSTEP 4 // 波形图横向步长 static WM_HWIN hWin; // 绘制波形图 void DrawWaveform(int *data, int len, int pos) { // 绘制背景 GUI_SetColor(GUI_BLACK); GUI_FillRect(0, YOFFSET, XSIZE, YSIZE + YOFFSET); // 绘制波形 GUI_SetColor(GUI_WHITE); for (int i = 0; i < XSIZE - XSTEP; i += XSTEP) { GUI_DrawLine(i, YSIZE + YOFFSET - data[(pos + i) % XSIZE], i + XSTEP, YSIZE + YOFFSET - data[(pos + i + XSTEP) % XSIZE]); } // 绘制刻度 GUI_SetColor(GUI_WHITE); GUI_SetFont(GUI_FONT_16B_ASCII); for (int i = 0; i <= YDIVS; i++) { int y = YSIZE * i / YDIVS; GUI_DrawLine(0, y + YOFFSET, 5, y + YOFFSET); char buf[16]; sprintf(buf, "%d", YDIVS - i); GUI_DispStringAt(buf, 8, y - 8 + YOFFSET); } for (int i = 0; i <= XDIVS; i++) { int x = XSIZE * i / XDIVS; GUI_DrawLine(x, YSIZE + YOFFSET, x, YSIZE + YOFFSET - 5); char buf[16]; sprintf(buf, "%d", i); GUI_DispStringAt(buf, x - 8, YSIZE + YOFFSET + 8); } // 更新显示 WM_InvalidateWindow(hWin); } // 模拟数据输入 void SimulateInput() { static int t = 0; static int data[XSIZE] = {0}; for (int i = 0; i < XSTEP; i++) { data[(t + i) % XSIZE] = 50 + 50 * sin(2 * PI * (t + i) / 100); } DrawWaveform(data, XSIZE, t); t += XSTEP; if (t >= XSIZE) { t = 0; } } // 主函数 int main() { GUI_Init(); hWin = WM_CreateWindow(0, 0, XSIZE, YSIZE + YOFFSET, WM_CF_SHOW, NULL, 0); while (1) { SimulateInput(); GUI_Delay(10); } return 0; } ``` 在这个示例代码中,我们使用了一个循环数组来存储波形图的数据,然后在每次绘制波形图时,只需要根据当前的位置来确定要绘制哪个数据点。这样,就可以实现扫描线从左到右根据数据前进的效果了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FSYo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值